CSS-selectors bieden een krachtige manier om specifieke inhoud uit HTML-pagina's te targeten en te extraheren. Deze uitgebreide gids behandelt alles wat u moet weten om CSS-selectors te gebruiken voor webscraping in Python.
Inleiding tot CSS-kiezers
Met CSS-kiezers kunt u elementen op een webpagina selecteren op basis van ID, klasse, tagnaam, attributen en meer. Hier zijn enkele voorbeelden:
div
- Selecteer allesgeeft je de mogelijkheid#container
– Selecteer element met id="container".item
– Selecteer elementen met class="item"a[href^="http"]
– Selecteer ankertags waarbij href begint met http
Er zijn meer dan 50 verschillende CSS-selectortypen en combinaties beschikbaar. Dit omvat tag-, ID-, klasse-, attribuut-, pseudo-klasse-, positionele, status- en lexicale selectors.
Enkele belangrijke selectortypen zijn:
Keuzeschakelaar | Voorbeeld | Omschrijving |
---|---|---|
Type | a | Selecteert alle elementen van een bepaald tagtype |
ID | #container | Selecteert een element met een specifiek id-attribuut |
Klasse | .item | Selecteert elementen met een specifiek klasse-attribuut |
Kenmerk | a[target] | Selecteer elementen met een specifiek attribuut |
Pseudo-klasse | a:hover | Selecteer elementen in een specifieke staat |
Deze kunnen op verschillende manieren worden gecombineerd om elementen zeer nauwkeurig te targeten. Bijvoorbeeld:
div.content table.data tr.highlight > td
Wat neerkomt op:
div.content
-<div>
elementen met class="content"table.data
-<table>
elementen met class="data" binnen de<div>
tr.highlight
-<tr>
elementen met class="highlight" binnen de<table>
> td
-<td>
elementen die directe kinderen zijn van de<tr>
Zoals u kunt zien, kunt u met CSS-kiezers heel precies inzoomen op elementen in de HTML-hiërarchie en deze specificeren. Dit maakt ze van onschatbare waarde voor het extraheren van specifieke gegevens uit webpagina's.
Uit onderzoek blijkt dat CSS-ID's en -klassen op meer dan 90% van de sites worden gebruikt om styling mogelijk te maken. Deze prevalentie maakt ze ook ideaal voor het selecteren van inhoud om te schrapen.
CSS-kiezers gebruiken in Python
Populaire Python-bibliotheken zoals BeautifulSoup en Parsel hebben ingebouwde ondersteuning voor CSS-selectors:
Mooie soep
Om CSS-selectors in BeautifulSoup te gebruiken, roept u de select()
methode op een BeautifulSoup
voorwerp:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html)
links = soup.select(‘a‘) # All anchor tags
first_link = soup.select_one(‘a‘) # First anchor tag
select()
retourneert een lijst met alle overeenkomende elementen.select_one()
retourneert alleen de eerste wedstrijd.
perceel
De Parsel-bibliotheek biedt een vergelijkbare API:
from parsel import Selector
selector = Selector(html)
links = selector.css(‘a‘).getall()
first_link = selector.css(‘a‘).get()
.css()
voert de CSS-selectors uit.getall()
geeft alle overeenkomsten terug.get()
geeft de eerste wedstrijd terug
Parsel wordt intern gebruikt door het Scrapy webscraping-framework.
Bibliotheken vergelijken
Zowel BeautifulSoup als Parsel hebben vrijwel identieke CSS-selectorfunctionaliteit. Parsel is iets sneller in benchmarks, maar BeautifulSoup biedt extra functies zoals het zoeken en wijzigen van de DOM.
Voor de meeste scrapdoeleinden is hun CSS-selectorondersteuning uitwisselbaar.
Voorbeelden van CSS-kiezers
Laten we nu enkele specifieke voorbeelden bekijken van het gebruik van CSS-selectors om gegevens te schrapen:
Elementen ophalen op tagnaam
Selecteer alle hyperlinks op een pagina:
links = soup.select(‘a‘)
Dit komt overeen met elk <a>
ankertagelementen.
Selecteer Element op ID
Krijg een formulier op een pagina met een specifieke ID:
login_form = soup.select_one(‘#loginForm‘)
De #
prefix geeft aan dat het overeenkomt met het id-attribuut. Hiermee wordt het element met geselecteerd id="loginForm"
.
ID's moeten uniek zijn binnen een pagina, dus er wordt altijd één element geretourneerd.
Elementen ophalen op klassenaam
Selecteer alle pagina-items met een specifieke klasse:
products = soup.select(‘.product-item‘)
De .
voorvoegsel geeft een klassenkiezer aan. Hiermee worden alle elementen geselecteerd met class="product-item"
.
Houd er rekening mee dat klassen opnieuw kunnen worden gebruikt, zodat deze met meerdere elementen kunnen overeenkomen.
Selecteer op attribuutwaarde
Extraheer invoervelden op basis van hun type-attribuut:
text_inputs = soup.select(‘input[type="text"]‘)
De [attribute="value"]
Met de syntaxis kunt u matchen op basis van specifieke attribuutwaarden.
Combineer meerdere selectors
Selecteer ankers binnen een specifieke zijbalkdiv:
sidebar_links = soup.select(‘div.sidebar a.highlight‘)
Dit komt overeen <a>
elementen met class="highlight"
binnen <div class="sidebar">
.
Meerdere selectors kunnen worden gecombineerd door ze te scheiden met een spatie die onderliggende elementen selecteert.
Gegevens schrapen met CSS-kiezers
Nadat u elementen heeft geëxtraheerd, kunnen CSS-kiezers worden gebruikt om gegevens te schrapen:
for product in soup.select(‘.product‘):
name = product.select_one(‘.product-name‘).text
price = product.select_one(‘.product-price‘).text
print(name, price)
Dit loopt door .product
elementen, en schraapt de .product-name
en .product-price
waarden uit elk productblok.
Het voordeel van CSS-selectors is dat u de gewenste gegevens kunt isoleren van de omringende HTML.
Schraapvoorbeeld - Wikipedia-infoboxen
Denk bijvoorbeeld aan schrapen infoboxen van Wikipedia:
url = ‘https://en.wikipedia.org/wiki/Abraham_Lincoln‘
soup = BeautifulSoup(requests.get(url).text)
infobox = soup.select_one(‘.infobox‘)
title = infobox.select_one(‘.fn‘).text
born = infobox.select_one(‘.bday‘).text
office = infobox.select_one(‘.label[style*=bold]‘).text
print(title) # Abraham Lincoln
print(born) # February 12, 1809
print(office) # 16th President of the United States
Dit isoleert de inhoud van de infobox met behulp van .infobox
class en extraheert vervolgens specifieke velden met behulp van geneste tag-, klasse- en attribuutselectors.
Zoals u kunt zien, kunt u door verschillende selectortypen aan elkaar te koppelen, de gegevens die u nodig hebt, verfijnen.
Gegevens uit een tabel schrapen
Selectors kunnen ook helpen bij het schrapen van tabelgegevens:
url = ‘https://www.example.com/data.html‘
soup = BeautifulSoup(requests.get(url).text)
table = soup.select_one(‘table.data-table‘)
headers = [h.text for h in table.select(‘th‘)]
rows = []
for row in table.select(‘tr‘):
cells = [d.text for d in row.select(‘td‘)]
rows.append(dict(zip(headers, cells)))
print(rows)
Hiermee extraheert u een gegevenstabel, leest u de headerlabels, doorloopt u vervolgens de rijen en bouwt u een woordenboek op van de header-celparen.
CSS-selectors maken het eenvoudig om gestructureerde gegevens te schrapen.
Beperkingen van CSS-kiezers voor scrapen
Een tekortkoming van CSS-selectors is dat ze alleen statische HTML kunnen parseren en niet werken met inhoud die dynamisch via JavaScript wordt geladen. Voor het scrapen van moderne sites zijn aanvullende tools nodig, zoals Selenium of browserautomatisering.
Ze bieden ook een beperkte mogelijkheid om bovenliggende elementen te doorlopen en te selecteren. Chaining kan dus alleen in een hiërarchie naar beneden gaan, niet naar boven.
Desondanks blijven CSS-selectors een essentieel hulpmiddel voor scraping vanwege hun alomtegenwoordigheid, snelheid en gemak voor gegevensextractie.
CSS-kiezers aan elkaar koppelen
Chaining maakt het mogelijk om door afstammingselementen te boren:
rows = soup.select(‘div#content table.data tr‘)
for row in rows:
name = row.select_one(‘td.name‘).text
price = row.select_one(‘td.price‘).text
print(name, price)
Eerst alle <tr>
rijen worden geselecteerd en vervolgens specifiek <td>
cellen uit elke rij worden geëxtraheerd door ketening.
Door selectors in combinatie te koppelen, kunnen gegevens worden geschrapt in relatie tot de omringende structuur en inhoud.
Geavanceerde CSS-kiezers
Er zijn ook enkele meer geavanceerde CSS-selectormogelijkheden die de moeite waard zijn:
wildcards
De *
jokertekenselector komt overeen met elk element:
panels = soup.select(‘div.panel *‘) # All descendants
Kenmerkkiezers
Complexere attribuutmatching is mogelijk:
input[type^="text"] # Type starts with "text"
a[href$=".pdf"] # Href ends with ".pdf"
div[class*="head"] # Class contains "head"
Pseudo-kiezers
Speciale staatskiezers zoals :hover
, :visited
enz. Bijvoorbeeld:
a:visited {color: purple}
Ondersteuning varieert per parser. Sommige pseudo-selectors houden van :contains()
zijn aangepaste extensies in plaats van CSS.
Broeder-kiezers
Doel gebaseerd op broers en zussen, bijvoorbeeld aangrenzende broers en zussen p + ul
vondsten <ul>
onmiddellijk daarna <p>
.
Ontkenning
:not(selector)
sluit overeenkomende elementen uit.
Deze extra keuzeschakelaars zorgen voor een nog nauwkeurigere controle bij het schrapen.
Interactieve sites schrapen
Hoewel CSS-selectors alleen werken op statische HTML, zijn er manieren om ze te gebruiken bij het schrapen van interactieve pagina's met door JavaScript gegenereerde inhoud:
Browser-automatisering
Tools zoals Selenium kunnen een browser aansturen om JavaScript weer te geven voordat het wordt geparseerd met CSS-selectors:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get(url)
soup = BeautifulSoup(driver.page_source)
results = soup.select(‘#results .result‘)
Dit maakt het mogelijk om elementen te selecteren nadat JS is uitgevoerd.
Headless Browsen
Voor headless scraping bieden tools zoals Puppeteer en Playwright ondersteuning voor CSS-selector:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto(url)
html = page.content()
soup = BeautifulSoup(html)
De pagina-inhoud na JavaScript-weergave kan worden geparseerd.
Browser-extensies
Browserextensies zoals SelectorGadget schrapen CSS-selectors door netwerkverkeer en DOM te analyseren.
Met deze benaderingen kunnen CSS-selectors worden gebruikt op dynamische sites. De selectors komen nog steeds alleen overeen met HTML, maar worden dynamisch gegenereerd via JavaScript.
Beperkingen en uitdagingen
Hoewel CSS-selectors alomtegenwoordig en handig zijn, hebben ze wel enkele beperkingen:
Complexe sites schrapen
Selectors worstelen met een aantal complexe sitestructuren:
- Frames en iframes vereisen afzonderlijke parsering.
- Voor geavanceerde rasters en lay-outs zijn mogelijk complexe selectors nodig.
- Interactieve widgets en ingebedde apps vereisen alternatieve benaderingen.
Vaak is een mix van CSS-selectie en andere parseerlogica nodig.
Prestatieproblemen
Zeer lange en complexe selectors kunnen traag worden. Het nestelen van meer dan 3-4 niveaus diep moet worden vermeden.
Wij raden aan om de individuele selectors eenvoudig te houden, met niet meer dan 3-4 componenten. Koppel meerdere eenvoudige selectors aan elkaar in plaats van ingewikkelde afzonderlijke expressies.
Broze selectors
Targeting op basis van attributen zoals klasse en ID leidt tot broze selectors die gemakkelijk kapot gaan als deze waarden veranderen bij het opnieuw ontwerpen van de site.
Richt u waar mogelijk op elementen op basis van naam, positie en hiërarchie in plaats van op fragiele kenmerken. Of combineer meerdere selectors als back-ups.
DOM-overschrijdingslimieten
CSS-selectors kunnen alleen door de afstammelingenboom lopen, niet naar bovenliggende elementen.
XPath-expressies bieden een flexibeler traject, zowel omhoog als omlaag door een document.
Ondersteuning voor pseudokiezers
Klassieke CSS-pseudo-selectors zoals :visited
en :hover
hebben beperkte ondersteuning voor meerdere browsers in parsers. Aangepaste selectors zoals :contains()
zijn niet-standaard.
Vertrouw op eenvoudige pseudo-klassen zoals :first-child
in plaats van complexe pseudo-selectors.
Alternatieven voor CSS-kiezers
Hoewel ze onmisbaar zijn, zijn CSS-selectors niet het enige spel in de stad voor het parseren van HTML:
XPath
XPath is een querytaal voor het selecteren van knooppunten in XML/HTML-documenten en biedt een alternatief voor CSS.
Voors:
- Krachtiger doorkruisen van de documentstructuur.
- Robuuste standaard onderhouden door W3C.
nadelen:
- Uitgebreide en complexe syntaxis.
- De prestaties kunnen langzamer zijn.
regex
Reguliere expressies kunnen tekstpatronen extraheren:
Voors:
- Flexibele, krachtige patroonafstemming.
nadelen:
- Rommelig bij het parseren van geneste HTML.
- Geen ingebouwde ondersteuning voor traversal.
In de praktijk biedt een combinatie van CSS-selectors, XPath en Regex vaak de meest robuuste mogelijkheden voor webscraping op industriële schaal.
Hulpmiddelen en bibliotheken
Hier zijn enkele essentiële hulpmiddelen voor het werken met CSS-selectors:
- Selectorgadget – Browserextensie om selectors te genereren.
- Toneelschrijver – Headless scraper met CSS-selectorondersteuning.
- Scrapy – Webscraping-framework met behulp van Parsel- en CSS-selectors.
- poppenspeler – Chroomschrapen zonder hoofd.
- Mooie soep – Toonaangevende Python HTML-parser.
Deze bieden alles wat nodig is om CSS-selectors te gebruiken voor productie-webscraping.
Conclusie
CSS-selectors bieden een veelzijdig en alomtegenwoordig mechanisme voor het extraheren van gegevens uit webpagina's. De prevalentie van id's en klassen in HTML maakt ze perfect om in te zoomen en precies de inhoud te schrappen die u nodig heeft.
Door de verscheidenheid aan selectortypen te beheersen en deze te combineren door middel van ketening en nesting, is uiterst nauwkeurig richten mogelijk. Met de kracht van Python-bibliotheken zoals BeautifulSoup en Parsel zijn CSS-selectors een essentiële techniek voor elke webscraper.