Meteen naar de inhoud

Hoe CSS-kiezers te gebruiken voor webscrapen in Python

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 alles
    geeft 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:

KeuzeschakelaarVoorbeeldOmschrijving
TypeaSelecteert alle elementen van een bepaald tagtype
ID#containerSelecteert een element met een specifiek id-attribuut
Klasse.itemSelecteert elementen met een specifiek klasse-attribuut
Kenmerka[target]Selecteer elementen met een specifiek attribuut
Pseudo-klassea:hoverSelecteer 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.

Doe mee aan het gesprek

Uw e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd *