Webpagina's schrapen in Python met Beautiful Soup The Basics

In een vorige zelfstudie heb ik je laten zien hoe je de module Verzoeken kunt gebruiken om webpagina's te openen met Python. De tutorial behandelde een heleboel onderwerpen zoals het maken van GET / POST-verzoeken en het downloaden van dingen zoals afbeeldingen of PDF's op programmatische wijze. Het enige wat ontbrak in die zelfstudie was een gids over het schrapen van webpagina's die je hebt geopend met behulp van Verzoeken om de informatie op te halen die je nodig hebt.

In deze tutorial leer je over Beautiful Soup, een Python-bibliotheek om gegevens uit HTML-bestanden te extraheren. De focus in deze tutorial ligt op het leren van de basisprincipes van de bibliotheek, en geavanceerdere onderwerpen komen aan de orde in de volgende tutorial. Let op: deze tutorial gebruikt Beautiful Soup 4 voor alle voorbeelden.

Installatie

Je kunt Beautiful Soup 4 gebruiken met Pip. De pakketnaam is beautifulsoup4. Het zou op zowel Python 2 als Python 3 moeten werken.

$ pip installeer beautifulsoup4

Als u geen pip op uw systeem hebt geïnstalleerd, kunt u de Beautiful Soup 4-broncode tarball direct downloaden en installeren met behulp van setup.py.

$ python setup.py installeren

BeautifulSoup is oorspronkelijk verpakt als Python 2-code. Wanneer u het installeert voor gebruik met Python 3, wordt het automatisch bijgewerkt naar Python 3-code. De code wordt niet geconverteerd, tenzij u het pakket installeert. Hier zijn enkele veelvoorkomende fouten die u wellicht opmerkt:

  • De "Geen module met de naam HTMLParser" ImportError treedt op wanneer u de Python 2-versie van de code onder Python 3 gebruikt.
  • De "Geen module genaamd html.parser" ImportError treedt op wanneer u de Python 3-versie van de code onder Python 2 gebruikt.

Beide fouten hierboven kunnen worden gecorrigeerd door Beautiful Soup te verwijderen en opnieuw te installeren.

Een Parser installeren

Voordat we de verschillen bespreken tussen verschillende parsers die u kunt gebruiken met Beautiful Soup, laten we de code schrijven om een ​​soep te maken.

van bs4 import BeautifulSoup soup = BeautifulSoup ("

Dit is ongeldige HTML

"," html.parser ")

De beautifulSoup object kan twee argumenten accepteren. Het eerste argument is de eigenlijke opmaak en het tweede argument is de parser die u wilt gebruiken. De verschillende parsers zijn: html.parser, lxml en html5lib. De lxml parser heeft twee versies, een HTML-parser en een XML-parser.

De html.parser is een ingebouwde parser en werkt niet zo goed in oudere versies van Python. U kunt de andere parsers installeren met behulp van de volgende opdrachten:

$ pip installeer lxml $ pip installeer html5lib

De lxml parser is erg snel en kan worden gebruikt om snel bepaalde HTML te parseren. Aan de andere kant, de html5lib parser is erg langzaam, maar het is ook extreem mild. Hier is een voorbeeld van het gebruik van elk van deze parsers:

soup = BeautifulSoup ("

Dit is ongeldige HTML

"," html.parser ") afdrukken (soep) #

Dit is ongeldige HTML

soup = BeautifulSoup ("

Dit is ongeldige HTML

"," lxml ") afdrukken (soep) #

Dit is ongeldige HTML

soup = BeautifulSoup ("

Dit is ongeldige HTML

"," xml ") afdrukken (soep) # #

Dit is ongeldige HTML

soup = BeautifulSoup ("

Dit is ongeldige HTML

"," html5lib ") afdrukken (soep) #

Dit is ongeldige HTML

De verschillen die in het bovenstaande voorbeeld worden geschetst, doen er alleen toe wanneer u ongeldige HTML parseert. Het merendeel van de HTML op het web is echter misvormd. Als u deze verschillen kent, kunt u enkele fouten in de parsering oplossen en bepalen welke parser u in een project wilt gebruiken. Over het algemeen, de lxml parser is een zeer goede keuze.

Objecten in mooie soep

Beautiful Soup analyseert het gegeven HTML-document in een structuur van Python-objecten. Er zijn vier Python-hoofdobjecten die u moet kennen: LabelNavigableStringbeautifulSoup, en Commentaar.

De Label object verwijst naar een werkelijke XML- of HTML-tag in het document. U kunt de naam van een tag gebruiken met tag.name. U kunt de naam van een tag ook op iets anders instellen. De naamswijziging zal zichtbaar zijn in de opmaak gegenereerd door Beautiful Soup.

U kunt verschillende attributen gebruiken, zoals de klasse en id van een tag tag [ 'class'] en tag [ 'id'] respectievelijk. U kunt ook het hele woordenboek van attributen gebruiken met tag.attrs. U kunt ook de kenmerken van een tag toevoegen, verwijderen of wijzigen. De attributen zoals die van een element klasse die meerdere waarden kunnen aannemen, worden opgeslagen als een lijst.

De tekst in een tag wordt opgeslagen als een NavigableString in mooie soep. Het heeft een paar bruikbare methoden zoals vervangen_door ( "string") om de tekst binnen een tag te vervangen. Je kunt ook een NavigableString naar unicode string met unicode ().

Met Beautiful Soup heeft u ook toegang tot de opmerkingen op een webpagina. Deze opmerkingen worden opgeslagen als een Commentaar object, dat eigenlijk ook een is NavigableString.

Je hebt al geleerd over de beautifulSoup object in het vorige gedeelte. Het wordt gebruikt om het document als geheel weer te geven. Omdat het geen echt object is, heeft het geen naam of attributen.

De titel, kopteksten en links ophalen

U kunt de paginatitel en andere dergelijke gegevens heel gemakkelijk extraheren met Beautiful Soup. Laten we de Wikipedia-pagina over Python schrapen. Eerst moet u de opmaak van de pagina krijgen met behulp van de volgende code op basis van de module Zelfstudie van verzoeken om toegang te krijgen tot webpagina's.

importeer aanvragen van bs4 import BeautifulSoup req = requests.get ('https://en.wikipedia.org/wiki/Python_ (programming_language)') soup = BeautifulSoup (req.text, "lxml")

Nu je de soep hebt gemaakt, kun je de titel van de webpagina gebruiken met de volgende code:

soup.title # Python (programmeertaal) - Wikipedia soup.title.name # 'title' soup.title.string # 'Python (programmeertaal) - Wikipedia'

U kunt de webpagina ook schrapen voor andere informatie, zoals de hoofdkop of de eerste alinea, hun klassen of de ID kaart attribuut.

soup.h1 # 

Python (programmeertaal)

soup.h1.string # 'Python (programmeertaal)' soup.h1 ['class'] # ['firstHeading'] soup.h1 ['id'] # 'firstHeading' soup.h1.attrs # 'class': ['firstHeading'], 'id': 'firstHeading', 'lang': 'en' soup.h1 ['class'] = 'firstHeading, mainHeading' soup.h1.string.replace_with ("Python - Programming Language" ) del soup.h1 ['lang'] del soup.h1 ['id'] soup.h1 #

Python - programmeertaal

Op dezelfde manier kunt u alle links of subkopjes in een document doorlopen met behulp van de volgende code:

voor sub_heading in soup.find_all ('h2'): print (sub_heading.text) # alle subtitels zoals Inhoud, Geschiedenis [bewerken] ... 

Navigeren door de DOM

U kunt door de DOM-structuur navigeren met behulp van normale tagnamen. Het koppelen van deze tagnamen kan u helpen de boom dieper te navigeren. U kunt bijvoorbeeld de eerste link in de eerste alinea van de gegeven Wikipedia-pagina krijgen door deze te gebruiken soup.p.a. Alle links in de eerste paragraaf zijn toegankelijk via soup.p.find_all ( 'a').

U kunt ook alle kinderen van een tag als een lijst openen met behulp van tag.contents. Om de kinderen bij een specifieke index te krijgen, kunt u gebruiken tag.contents [index]. U kunt ook de kinderen van een tag herhalen met behulp van de .kinderen attribuut.

Beide .kinderen en .inhoud zijn alleen nuttig als u toegang wilt tot de afstammelingen van het directe of eerste niveau van een tag. Om alle afstammelingen te krijgen, kunt u de .nakomelingen attribuut.

print (soup.p.contents) # [Python, 'is een veel gebruikte', ... de volledige lijst] print (soup.p.contents [10]) # leesbaarheid voor kind in soep.p.kinderen: print (child.name) # b # Geen # a # Geen # a # Geen # ... enzovoort.

U kunt ook de ouder van een element openen met behulp van de .ouder attribuut. Op dezelfde manier hebt u toegang tot alle voorouders van een element met behulp van de .ouders attribuut. De ouder van het hoogste niveau tag is het beautifulSoup Object zelf en het bovenliggende element is None.

print (soup.p.parent.name) # div voor ouder in soep.p.ouders: print (parent.name) # div # div # div # body # html # [document]

U kunt de vorige en volgende broer of zus van een element openen met behulp van de .previous_sibling en .next_sibling attributen. 

Voor twee elementen als broers en zussen, moeten ze dezelfde ouder hebben. Dit betekent dat het eerste kind van een element geen vorige broer of zus heeft. Evenzo heeft het laatste kind van het element geen volgende broer of zus. In echte webpagina's zullen de vorige en volgende broers en zussen van een element hoogstwaarschijnlijk een nieuw lijnteken zijn. 

U kunt ook alle broers en zussen van een element met behulp van .previous_siblings en .next_siblings.

soup.head.next_sibling # '\ n' soup.p.a.next_sibling # 'for' soup.p.a.previous_sibling # 'is een veel gebruikte' print (soup.p.b.previous_sibling) # None

U kunt naar het element gaan dat onmiddellijk na het huidige element komt met behulp van de .next_element attribuut. Om toegang te krijgen tot het element dat direct voor het huidige element komt, gebruikt u de .previous_element attribuut. 

Op dezelfde manier kunt u alle elementen herhalen die vóór en na het huidige element komen .previous_elements en .next_elements respectievelijk.

Laatste gedachten

Nadat u deze zelfstudie hebt voltooid, moet u nu een goed inzicht hebben in de belangrijkste verschillen tussen verschillende HTML-parsers. Je zou nu ook door een webpagina kunnen navigeren en belangrijke gegevens kunnen extraheren. Dit kan handig zijn als u alle koppen of links op een bepaalde website wilt analyseren.

In het volgende deel van de serie leert u hoe u de Beautiful Soup-bibliotheek gebruikt om de DOM te zoeken en aan te passen.