beautifulsoup
Ortungselemente
Suche…
Suchen Sie nach einem Element in BeautifulSoup einen Text
Stellen Sie sich vor, Sie haben folgendes HTML:
<div>
<label>Name:</label>
John Smith
</div>
Und Sie müssen den Text "John Smith" nach dem label
Element finden.
In diesem Fall können Sie das label
Element nach Text .next_sibling
und dann die .next_sibling
Eigenschaft verwenden :
from bs4 import BeautifulSoup
data = """
<div>
<label>Name:</label>
John Smith
</div>
"""
soup = BeautifulSoup(data, "html.parser")
label = soup.find("label", text="Name:")
print(label.next_sibling.strip())
Druckt John Smith
.
Verwenden von CSS-Selektoren zum Suchen von Elementen in BeautifulSoup
BeautifulSoup unterstützt CSS-Selektoren nur begrenzt , deckt jedoch die am häufigsten verwendeten ab. Verwenden Sie die select()
-Methode, um mehrere Elemente zu finden, und select_one()
, um ein einzelnes Element zu finden.
Grundbeispiel:
from bs4 import BeautifulSoup
data = """
<ul>
<li class="item">item1</li>
<li class="item">item2</li>
<li class="item">item3</li>
</ul>
"""
soup = BeautifulSoup(data, "html.parser")
for item in soup.select("li.item"):
print(item.get_text())
Drucke:
item1
item2
item3
Kommentare suchen
Um nach Kommentaren in BeautifulSoup
, verwenden Sie den text
(oder die string
in den letzten Versionen), um den Typ als Comment
prüfen:
from bs4 import BeautifulSoup
from bs4 import Comment
data = """
<html>
<body>
<div>
<!-- desired text -->
</div>
</body>
</html>
"""
soup = BeautifulSoup(data, "html.parser")
comment = soup.find(text=lambda text: isinstance(text, Comment))
print(comment)
Druckt den desired text
.
Filterfunktionen
Mit BeautifulSoup können Sie Ergebnisse filtern, indem Sie eine Funktion für find_all
und ähnliche Funktionen find_all
. Dies kann sowohl für komplexe Filter als auch für die Wiederverwendung von Code nützlich sein.
Grundlegende Verwendung
Definieren Sie eine Funktion, die ein Element als einziges Argument verwendet. Die Funktion sollte True
wenn das Argument übereinstimmt.
def has_href(tag):
'''Returns True for tags with a href attribute'''
return bool(tag.get("href"))
soup.find_all(has_href) #find all elements with a href attribute
#equivilent using lambda:
soup.find_all(lambda tag: bool(tag.get("href")))
Ein anderes Beispiel, bei dem Tags mit einem href
Wert gefunden werden, die nicht mit beginnen
Zusätzliche Argumente zum Filtern von Funktionen bereitstellen
Da die an find_all
Funktion nur ein Argument enthalten kann, ist es manchmal nützlich, 'Funktionsfactories' zu erstellen, die Funktionen erzeugen, die für find_all
. Dies ist hilfreich, um die Tag-Finding-Funktionen flexibler zu gestalten.
def present_in_href(check_string):
return lambda tag: tag.get("href") and check_string in tag.get("href")
soup.find_all(present_in_href("/partial/path"))
Zugriff auf interne Tags und ihre Attribute des ursprünglich ausgewählten Tags
Nehmen wir an, Sie haben nach der Auswahl mit soup.find('div', class_='base class')
ein html
:
from bs4 import BeautifulSoup
soup = BeautifulSoup(SomePage, 'lxml')
html = soup.find('div', class_='base class')
print(html)
<div class="base class">
<div>Sample text 1</div>
<div>Sample text 2</div>
<div>
<a class="ordinary link" href="https://example.com">URL text</a>
</div>
</div>
<div class="Confusing class"></div>
'''
Und wenn Sie zugreifen möchten <a>
- Tag des href
, können Sie es auf diese Weise tun:
a_tag = html.a
link = a_tag['href']
print(link)
https://example.com
Dies ist nützlich, wenn Sie das <a>
-Tag nicht direkt auswählen können, da die attrs
keine eindeutige Identifikation attrs
Es gibt andere "Twin" -Tags <a>
auf der geparsten Seite. Sie können jedoch ein übergeordnetes Tag eindeutig auswählen, das das benötigte <a>
enthält.
Sammeln optionaler Elemente und / oder ihrer Attribute aus einer Reihe von Seiten
Betrachten wir die Situation, wenn Sie die Anzahl der Seiten analysieren und den Wert eines optionalen Elements (das auf einer Seite dargestellt werden kann und auf einer anderen Seite fehlen kann) für eine bestimmte Seite erfassen möchte.
Außerdem ist das Element selbst beispielsweise das üblichste Element auf der Seite, das heißt, es können keine bestimmten Attribute eindeutig lokalisiert werden. Sie sehen jedoch, dass Sie das übergeordnete Element richtig auswählen können und die Bestellnummer des gewünschten Elements in der jeweiligen Schachtelungsebene kennen.
from bs4 import BeautifulSoup
soup = BeautifulSoup(SomePage, 'lxml')
html = soup.find('div', class_='base class') # Below it refers to html_1 and html_2
Das gewünschte Element ist optional, daher kann es zwei Situationen für html
:
html_1 = '''
<div class="base class"> # №0
<div>Sample text 1</div> # №1
<div>Sample text 2</div> # №2
<div>!Needed text!</div> # №3
</div>
<div>Confusing div text</div> # №4
'''
html_2 = '''
<div class="base class"> # №0
<div>Sample text 1</div> # №1
<div>Sample text 2</div> # №2
</div>
<div>Confusing div text</div> # №4
'''
Wenn Sie html_1
, können Sie sammeln !Needed text!
vom Tag №3 auf diese Weise:
wanted tag = html_1.div.find_next_sibling().find_next_sibling() # this gives you whole tag №3
Es erhält zunächst №1 div
, wechselt dann zweimal zum nächsten div
auf derselben Verschachtelungsstufe, um zu №3 zu gelangen.
wanted_text = wanted_tag.text # extracting !Needed text!
Nützlich für diesen Ansatz ist, wenn Sie html_2
- der Ansatz gibt Ihnen keinen Fehler, es wird None
geben:
print(html_2.div.find_next_sibling().find_next_sibling())
None
Die Verwendung von find_next_sibling()
hier von entscheidender Bedeutung, da dadurch die Elementsuche nach der jeweiligen Verschachtelungsebene begrenzt wird. Wenn Sie find_next()
wird das Tag №4 erfasst und Sie möchten es nicht.
print(html_2.div.find_next().find_next())
<div>Confusing div text</div>
Sie können auch find_previous_sibling()
und find_previous()
erkunden, die find_previous_sibling()
umgekehrt funktionieren.
Alle beschriebenen Funktionen haben mehrere Varianten, um alle Tags abzufangen , nicht nur das erste:
find_next_siblings()
find_previous_siblings()
find_all_next()
find_all_previous()