beautifulsoup
Elementen zoeken
Zoeken…
Zoek een tekst achter een element in BeautifulSoup
Stel je voor dat je de volgende HTML hebt:
<div>
<label>Name:</label>
John Smith
</div>
En u moet de tekst "John Smith" achter het label
element zoeken.
In dat geval kunt u het vinden label
element door tekst en gebruik vervolgens .next_sibling
eigenschap :
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())
Prints John Smith
.
CSS-selectors gebruiken om elementen in BeautifulSoup te vinden
BeautifulSoup biedt beperkte ondersteuning voor CSS-selectors , maar dekt de meestgebruikte. Gebruik select()
methode select()
om meerdere elementen te vinden en select_one()
om een enkel element te vinden.
Basis voorbeeld:
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())
prints:
item1
item2
item3
Reacties zoeken
Om opmerkingen in BeautifulSoup
te vinden, gebruikt u het argument text
(of string
in de recente versies) en vinkt u het type aan als Comment
:
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)
Drukt desired text
.
Filter functies
Met BeautifulSoup kunt u resultaten filteren door een functie te find_all
voor alle find_all
en soortgelijke functies. Dit kan handig zijn voor complexe filters, maar ook als hulpmiddel voor hergebruik van code.
Basis gebruik
Definieer een functie waarvoor een element het enige argument is. De functie moet True
retourneren als het argument overeenkomt.
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")))
Een ander voorbeeld dat tags vindt met een href
waarde die niet beginnen
Aanvullende argumenten verstrekken voor filterfuncties
Omdat de functie die wordt doorgegeven aan find_all
maar één argument kan bevatten, is het soms handig om 'functiefabrieken' te maken die functies geschikt maken voor gebruik in find_all
. Dit is handig om uw tag-zoekfuncties flexibeler te maken.
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"))
Toegang tot interne tags en hun attributen van aanvankelijk geselecteerde tag
Laten we aannemen dat u een html
hebt gekregen na het selecteren met soup.find('div', class_='base class')
:
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>
'''
En als u toegang wilt tot de href
<a>
tag, kunt u dit op deze manier doen:
a_tag = html.a
link = a_tag['href']
print(link)
https://example.com
Dit is handig wanneer u niet rechtstreeks <a>
-tag kunt selecteren omdat de attrs
u geen unieke identificatie geven, er zijn andere "dubbele" <a>
-tags in geparseerde pagina. Maar u kunt op unieke wijze een bovenliggende tag selecteren die de benodigde <a>
bevat.
Het verzamelen van optionele elementen en / of hun attributen uit een reeks pagina's
Laten we de situatie bekijken wanneer u het aantal pagina's parseert en u waarde wilt verzamelen van een element dat optioneel is (kan op de ene pagina worden weergegeven en op een andere pagina afwezig zijn) voor een bepaalde pagina.
Bovendien is het element zelf bijvoorbeeld het meest gewone element op pagina, met andere woorden, geen specifieke attributen kunnen het uniek lokaliseren. Maar u ziet dat u het bovenliggende element correct kunt selecteren en dat u het bestelnummer van het gewenste element kent in het respectieve nestniveau.
from bs4 import BeautifulSoup
soup = BeautifulSoup(SomePage, 'lxml')
html = soup.find('div', class_='base class') # Below it refers to html_1 and html_2
Wanted-element is optioneel, dus er kunnen 2 situaties zijn voor 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
'''
Als je html_1
hebt, kun je deze verzamelen !Needed text!
van tag №3 op deze manier:
wanted tag = html_1.div.find_next_sibling().find_next_sibling() # this gives you whole tag №3
Het krijgt in eerste instantie №1 div
, dan schakelt 2 keer over naar de volgende div
op hetzelfde nestniveau om №3 te krijgen.
wanted_text = wanted_tag.text # extracting !Needed text!
Het nut van deze aanpak komt wanneer u html_2
krijgt - de aanpak geeft geen fouten, maar geeft None
:
print(html_2.div.find_next_sibling().find_next_sibling())
None
Het gebruik van find_next_sibling()
hier is van cruciaal belang omdat het zoeken van elementen per respectief find_next_sibling()
wordt beperkt. Als u find_next()
wordt tag find_next()
verzameld en wilt u het niet:
print(html_2.div.find_next().find_next())
<div>Confusing div text</div>
Je kunt ook find_previous_sibling()
en find_previous()
verkennen die recht tegenovergesteld werken.
Alle beschreven functies hebben hun miltiple- varianten om alle tags te vangen, niet alleen de eerste:
find_next_siblings()
find_previous_siblings()
find_all_next()
find_all_previous()