[PYTHON] Astuce BeautifulSoup: choisissez la balise en spécifiant le chemin

S'il y a une balise caractéristique dans la partie que vous souhaitez extraire de XML / HTML, BeautifulSoup peut rechercher cette balise en tant que mot-clé, ce qui est très utile. Cependant, s'il n'y a pas de balise avec de telles caractéristiques, il n'y a pas d'autre choix que de suivre les balises dans l'ordre de la balise racine à la balise cible. BeautifulSoup ne prend pas en charge XPATH, donc je suis un peu faible dans ce genre d'exploration.

Par conséquent, j'ai créé une fonction pour décider de la balise en spécifiant un chemin simple.

** Comment spécifier PATH ** (1) Forme de base - Les noms des éléments des balises sont séparés par '/' et classés dans l'ordre.   html/body/table/tr/td "Premier td sous le premier tr sous la première table sous le corps"

(2) Sélection des balises frères - Spécifiez l'ordre n (1 à) dans lequel les balises que vous souhaitez extraire apparaissent avec '[n]'   html/body/table[1]/tr[3]/td "Le premier td sous le troisième tr sous le premier tableau sous le corps"

b4_path.py


from bs4 import BeautifulSoup
import re

#<SUBROUTINE>###################################################################
# Function:Trouvez la balise racine de n'importe quelle balise
################################################################################
def root(self):
    if self.name == u'[document]':
        return self
    else:
        return [node for node in self.parents][-1]

BeautifulSoup.root = root

#<SUBROUTINE>###################################################################
# Function:Extraire la balise spécifique spécifiée dans le simple PATH
# 
################################################################################
def path(self, path):
    re_siblings = re.compile(r'(\w+)\[(\d+)\]')

    if path[0] == '/':
        node = self.root()
    else:
        node = self

    path = path.strip('/')
    for arrow in path.split('/'):
        if arrow == 'tbody':
            continue

        match = re_siblings.match(arrow)
        if match:
            arrow = match.group(1)
            num   = int(match.group(2))-1
            node  = node.find_all(arrow, recursive=False)[num]
        else:
            node  = getattr(node, arrow)
    return node
    
BeautifulSoup.path = path

#<TEST>#########################################################################
# Function:Routine de test
################################################################################
if __name__ == '__main__':
    soup = BeautifulSoup("""
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>

<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">...</p>
""")

    print soup.path('/html/body/p[2]/a[1]').prettify()

Recommended Posts

Astuce BeautifulSoup: choisissez la balise en spécifiant le chemin
Importez en spécifiant directement le chemin du répertoire
Astuce BeautifulSoup: demandez la balise racine
Installer en spécifiant la version avec pip
Lisez le fichier en spécifiant le code de caractère.
Décidons le cours de date par optimisation de combinaison
Trier les éléments d'un tableau en spécifiant des conditions
Le datetime Python3 est plus rapide en spécifiant simplement le fuseau horaire
Renommer le fichier en utilisant le chemin complet reçu par le shell
[Python] Récupère l'élément en spécifiant l'attribut name dans BeautifulSoup
Accédez à Github en spécifiant la clé SSH dans GitPython
Extraire l'élément en supprimant la balise contenue dans la chaîne de caractères
[Python] Supprimer en spécifiant une balise avec Beautiful Soup
Obtenez le chemin complet référencé par .lnk avec wsl