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()


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow