beautifulsoup
Hitta element
Sök…
Leta reda på en text efter ett element i BeautifulSoup
Föreställ dig att du har följande HTML:
<div>
<label>Name:</label>
John Smith
</div>
Och du måste hitta texten "John Smith" efter label
.
I det här fallet kan du hitta label
efter text och sedan använda .next_sibling
egenskapen :
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())
Skriver ut John Smith
.
Använda CSS-väljare för att hitta element i BeautifulSoup
BeautifulSoup har ett begränsat stöd för CSS-väljare , men täcker de vanligaste. Använd metoden select()
för att hitta flera element och select_one()
att hitta ett enda element.
Grundläggande exempel:
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())
Grafik:
item1
item2
item3
Hitta kommentarer
För att hitta kommentarer i BeautifulSoup
använder du text
(eller string
i de senaste versionerna) och kontrollerar typen som ska 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)
Skriver ut desired text
.
Filterfunktioner
Med BeautifulSoup kan du filtrera resultat genom att tillhandahålla en funktion för att find_all
och liknande funktioner. Detta kan vara användbart för komplexa filter samt ett verktyg för återanvändning av kod.
Grundläggande användning
Definiera en funktion som tar ett element som enda argument. Funktionen ska returnera True
om argumentet matchar.
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")))
Ett annat exempel som hittar taggar med ett href
värde som inte börjar med
Tillhandahålla ytterligare argument för att filtrera funktioner
Eftersom funktionen som skickas till find_all
bara kan ta ett argument är det ibland användbart att göra 'funktionsfabriker' som producerar funktioner som är lämpliga för användning i find_all
. Detta är användbart för att göra dina taggfunktioner mer flexibla.
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"))
Få åtkomst till interna taggar och deras attribut för den ursprungligen valda taggen
Låt oss anta att du fick en html
efter att ha valt med 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>
'''
Och om du vill få tillgång till <a>
taggens href
kan du göra det på detta sätt:
a_tag = html.a
link = a_tag['href']
print(link)
https://example.com
Detta är användbart när du inte direkt kan välja <a>
-tagg eftersom det är attrs
inte ger dig unik identifikation, det finns andra "tvilling" <a>
-taggar på den parsade sidan. Men du kan på ett unikt sätt välja en överordnad tagg som innehåller nödvändig <a>
.
Samla valfria element och / eller deras attribut från serier
Låt oss överväga situationen när du analyserar antal sidor och du vill samla värde från ett element som är valfritt (kan presenteras på en sida och kan vara frånvarande på en annan) för en patikulär sida.
Dessutom är själva elementet till exempel det vanligaste elementet på sidan, med andra ord kan inga specifika attribut unikt hitta det. Men du ser att du kan välja det överordnade elementet ordentligt och du vet önskat elementets ordernummer i respektive häckningsnivå.
from bs4 import BeautifulSoup
soup = BeautifulSoup(SomePage, 'lxml')
html = soup.find('div', class_='base class') # Below it refers to html_1 and html_2
Det önskade elementet är valfritt, så det kan finnas två situationer 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
'''
Om du har html_1
du samla in !Needed text!
från tagg nummer 3 på detta sätt:
wanted tag = html_1.div.find_next_sibling().find_next_sibling() # this gives you whole tag №3
Den får initialt №1 div
, sedan byter 2 gånger till nästa div
på samma häckningsnivå för att komma till №3.
wanted_text = wanted_tag.text # extracting !Needed text!
Användbarheten av detta tillvägagångssätt kommer när du får html_2
- tillvägagångssättet kommer inte att ge dig fel, det kommer att ge None
:
print(html_2.div.find_next_sibling().find_next_sibling())
None
Att använda find_next_sibling()
här är avgörande eftersom det begränsar elementets sökning med respektive häckningsnivå. Om du skulle använda find_next()
samlas tagg nr 4 och du vill inte ha det:
print(html_2.div.find_next().find_next())
<div>Confusing div text</div>
Du kan också utforska find_previous_sibling()
och find_previous()
som fungerar tvärtom.
Alla beskrivna funktioner har sina miltiple- varianter för att fånga alla taggar, inte bara den första:
find_next_siblings()
find_previous_siblings()
find_all_next()
find_all_previous()