Navigation i komplekse HTML-strukturer
Lær teknikker til effektivt at gennemløbe dybt indlejrede eller uregelmæssigt strukturerede HTML-dokumenter.
Navigation i komplekse HTML-strukturer er en gratis Webscraping og botudvikling-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Webscraping og botudvikling, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Webscraping og botudvikling-kurset indeholder 4 lektioner i alt.
Ud over simpel udtrækning
Hvad sker der, når de data, du skal bruge, ikke ligger pænt i et element med et entydigt ID eller en entydig klasse? Nogle gange har websider komplekse layout, der kræver en mere avanceret tilgang.
I denne lektion lærer du, hvordan du kan "gå" gennem HTML-strukturen og finde elementer baseret på deres relationer til andre elementer. Denne teknik kaldes gennemgang af HTML-træet.
HTML-træets struktur
Tænk på et HTML-dokument som et stamtræ. Hvert element (f.eks. <div>, <p> eller <h1>) er en "node".
- Forælder: Et element, der indeholder andre elementer.
- Underordnet: Et element, der ligger direkte inde i et andet element.
- Søskende: Elementer på samme niveau, der har samme forælder.
- Efterkommer: Ethvert element i en forælder, direkte eller indirekte.
Det er vigtigt at forstå disse relationer for at kunne navigere i komplekse sider.
Underordnede: Direkte efterkommere
Hvis du vil hente de direkte underordnede elementer fra et element, tilbyder BeautifulSoup et par muligheder. Egenskaben .contents returnerer en liste over alle underordnede elementer, herunder NavigableStrings (tekstnoder).
Egenskaben .children returnerer en iterator, som ofte bruger mindre hukommelse i store dokumenter. Lad os se et eksempel.
from bs4 import BeautifulSoup
html_doc = """
<div class="parent">
<p>Child 1</p>
<span>Child 2</span>
Text node
</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
parent_div = soup.find('div', class_='parent')
print("Using .contents:")
for child in parent_div.contents:
print(f"- {child.name or 'Text'}: {repr(child)[:20]}...")
print("\nUsing .children:")
for child in parent_div.children:
print(f"- {child.name or 'Text'}: {repr(child)[:20]}...")Bevæg dig op: Forældre
Nogle gange finder du et element, men har brug for oplysninger fra det element, der indeholder det. Med BeautifulSoup kan du nemt bevæge dig "op" gennem træet.
- Egenskaben
.parentgiver dig et elements direkte forælder. - Egenskaben
.parentsgiver dig en iterator over alle overordnede elementer helt op til dokumentets rod.
from bs4 import BeautifulSoup
html_doc = """
<div class="grandparent">
<div class="parent">
<p class="child">Hello</p>
</div>
</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
child_p = soup.find('p', class_='child')
print(f"Child: {child_p.name}")
print(f"Direct Parent: {child_p.parent.name}")
print("All Ancestors:")
for p in child_p.parents:
if p.name: # Filter out [document] and other non-tag elements
print(f"- {p.name}")Side om side: Enkeltstående søskende
Elementer på samme niveau kaldes søskende. Du kan bevæge dig mellem dem ved hjælp af .next_sibling og .previous_sibling.
Vær opmærksom på, at disse egenskaber også inkluderer objekter af typen "NavigableString", hvis der er mellemrum eller tekst direkte mellem dine tags. Du skal muligvis kontrollere, om resultatet er et tag.
from bs4 import BeautifulSoup
html_doc = """
<div class="items">
<p>Item 1</p>
<span>Item 2</span>
<p>Item 3</p>
</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
item_one = soup.find('p', string='Item 1')
# The next sibling after <p>Item 1</p> is usually a newline character (NavigableString)
# We need to find the *next tag* sibling
next_tag = item_one.next_sibling
while next_tag and not next_tag.name:
next_tag = next_tag.next_sibling
print(f"Item 1: {item_one.text}")
if next_tag:
print(f"Next tag sibling: {next_tag.text}")
else:
print("No next tag sibling found.")Alle søskende: next_siblings
Hvis du vil hente alle søskende, der kommer efter eller før et bestemt tag, kan du bruge iteratorerne .next_siblings og .previous_siblings.
Det er særdeles nyttigt, når du har fundet ét element og skal udtrække data fra alle relaterede elementer på samme niveau.
from bs4 import BeautifulSoup
html_doc = """
<div class="menu">
<a href="#home">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
home_link = soup.find('a', href='#home')
print("All next siblings after Home:")
for sibling in home_link.next_siblings:
if sibling.name == 'a': # Only interested in <a> tags
print(f"- {sibling.text}: {sibling['href']}")Ud over søskende: find_next
Nogle gange er de data, du skal bruge, ikke et direkte underordnet element eller et søskende, men optræder et sted senere i HTML-dokumentet i forhold til dit aktuelle element. Her kommer .find_next() og .find_all_next() ind i billedet.
Disse metoder søger i resten af dokumentet efter det aktuelle tag, uanset relationerne mellem forældre, underordnede og søskende. På samme måde søger .find_previous() og .find_all_previous() før det aktuelle tag.
from bs4 import BeautifulSoup
html_doc = """
<div class="header">
<h2>Section Title</h2>
</div>
<p>Some introductory text.</p>
<div class="content">
<p>First paragraph.</p>
<span>Important data!</span>
<p>Second paragraph.</p>
</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
section_title = soup.find('h2')
# Find the next <span> tag anywhere after the h2
important_data_span = section_title.find_next('span')
print(f"Section Title: {section_title.text}")
if important_data_span:
print(f"Data found after title: {important_data_span.text}")
# Find all <p> tags after the h2
all_next_paragraphs = section_title.find_all_next('p')
print("All paragraphs after title:")
for p in all_next_paragraphs:
print(f"- {p.text}")Kæd gennemgangsmetoder sammen
Gennemgangens virkelige styrke ligger i at kæde disse metoder sammen. Du kan begynde ét sted, bevæge dig til en forælder, finde et søskendeelement og derefter udtrække data fra dets underordnede elementer.
Det giver dig mulighed for at navigere gennem meget specifikke, komplekse stier, så du kan nå præcis de data, du har brug for, selv når de ikke kan adresseres direkte med en simpel selector.
from bs4 import BeautifulSoup
html_doc = """
<div class="product-listing">
<div class="product">
<h3>Laptop X</h3>
<p class="price">$1200</p>
</div>
<div class="product">
<h3>Mouse Y</h3>
<p class="price">$50</p>
</div>
</div>
<div class="summary">
<p>Total items: 2</p>
</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
# Find "Laptop X" and then get its price
laptop_h3 = soup.find('h3', string='Laptop X')
if laptop_h3:
# The price is a sibling of the h3
price_tag = laptop_h3.find_next_sibling('p', class_='price')
if price_tag:
print(f"{laptop_h3.text} price: {price_tag.text}")
# Find the product listing, then get the text of the summary's paragraph
product_listing_div = soup.find('div', class_='product-listing')
if product_listing_div:
summary_div = product_listing_div.find_next_sibling('div', class_='summary')
if summary_div:
summary_text = summary_div.find('p').text
print(f"Summary: {summary_text}")Håndtering af tekstnoder
Når du gennemgår træet, møder du ofte objekter af typen NavigableString. De repræsenterer tekstindhold, der ikke er omsluttet af sit eget HTML-tag, f.eks. tomme tegn (linjeskift og mellemrum) mellem tags.
BeautifulSoup behandler disse som separate noder i træet. Når du bruger gennemgangsmetoder som .next_sibling, kan du få en NavigableString, før du får det næste faktiske tag. Kontrollér altid .name eller type(), hvis du kun vil have tags.
from bs4 import BeautifulSoup
html_doc = """
<div>
Hello
<p>World</p>
!
</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
div_tag = soup.find('div')
print("Children of the div:")
for child in div_tag.children:
if child.name:
print(f"- Tag: {child.name}, Text: {child.text}")
else:
print(f"- Text Node: {repr(child)}")
# Accessing a specific NavigableString
hello_text_node = list(div_tag.children)[0]
print(f"\nFirst child (text node): '{hello_text_node.strip()}'")Udfordring: Gennemgang
Overvej følgende HTML-udsnit. Du vil udtrække status for "Availability" for "Product B". Hvilken sekvens af BeautifulSoup-gennemgangsmetoder vil korrekt hente teksten "In Stock", når du starter fra <h3>-tagget for "Product B"?
<html>
<body>
<div class="catalog">
<div class="item">
<h3>Product A</h3>
<p>Price: $10</p>
<span>Status: Out of Stock</span>
</div>
<div class="item">
<h3>Product B</h3>
<p>Price: $20</p>
<span>Availability: In Stock</span>
</div>
<div class="item">
<h3>Product C</h3>
<p>Price: $30</p>
<span>Status: Low Stock</span>
</div>
</div>
</body>
</html>Opsummering: Bliv dygtig til gennemgang
Tillykke! Du har lært at navigere i komplekse HTML-strukturer ved hjælp af BeautifulSoups effektive gennemgangsmetoder.
- Vi undersøgte, hvordan man bevæger sig op (
.parent,.parents), ned (.contents,.children) og sidelæns (.next_sibling,.previous_sibling,.next_siblings,.previous_siblings) i HTML-træet. - Du så også, hvordan du kan finde elementer hvor som helst efter eller før et aktuelt tag ved hjælp af
.find_next()og.find_previous(). - Når du mestrer disse teknikker, kan du udtrække data fra selv de mest udfordrende websider med uregelmæssig struktur.
Derefter dykker vi ned i CSS-selectors for at udtrække data endnu mere præcist!
Lær Python med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 12
- Lektioner
- 48
Ofte stillede spørgsmål
Er lektionen “Navigation i komplekse HTML-strukturer” gratis?
Ja — alle 3 lektioner i læringssporet Webscraping og botudvikling, inklusive “Navigation i komplekse HTML-strukturer”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Webscraping og botudvikling-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Navigation i komplekse HTML-strukturer”?
Lær teknikker til effektivt at gennemløbe dybt indlejrede eller uregelmæssigt strukturerede HTML-dokumenter. Du øver dig i Webscraping og botudvikling med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Webscraping og botudvikling?
Der kræves ingen tidligere erfaring. Webscraping og botudvikling på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Navigation i komplekse HTML-strukturer”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Webscraping og botudvikling-lektion?
Ja. Alle Webscraping og botudvikling-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Navigation i komplekse HTML-strukturer
- CSS-selektorer til præcist dataudtræk
- XPath til robust udvælgelse
- Udtrækning af data fra HTML-tabeller