Skraping av nettsider i Python med vakker suppe Grunnleggende

I en tidligere veiledning viste jeg deg hvordan du bruker Request-modulet for å få tilgang til nettsider ved hjelp av Python. Opplæringen dekket mange emner som å lage GET / POST-forespørsler og laste ned ting som bilder eller PDF-filer programmatisk. Den eneste tingen som mangler fra den opplæringen var en veiledning om å skrape nettsider du åpnet ved å bruke Forespørsler for å trekke ut den informasjonen du trenger.

I denne opplæringen lærer du om Beautiful Soup, som er et Python-bibliotek for å pakke ut data fra HTML-filer. Fokuset i denne opplæringen vil være på å lære det grunnleggende i biblioteket, og mer avanserte emner vil bli dekket i neste veiledning. Vær oppmerksom på at denne opplæringen bruker Beautiful Soup 4 for alle eksemplene.

Installasjon

Du kan installere Beautiful Soup 4 ved hjelp av pip. Pakkenavnet er beautifulsoup4. Det skal fungere på både Python 2 og Python 3.

$ pip installere beautifulsoup4

Hvis du ikke har pip installert på systemet, kan du laste ned Beautiful Soup 4 kilde tarball direkte og installere den ved hjelp av setup.py.

$ python setup.py installere

BeautifulSoup er opprinnelig pakket som Python 2-kode. Når du installerer den for bruk med Python 3, oppdateres den automatisk til Python 3-koden. Koden vil ikke bli konvertert med mindre du installerer pakken. Her er noen vanlige feil som du kanskje merker:

  • "Ingen modul kalt HTMLParser" ImportError oppstår når du kjører Python 2-versjonen av koden under Python 3.
  • "Ingen modul kalt html.parser" ImportError oppstår når du kjører Python 3-versjonen av koden under Python 2.

Begge feilene ovenfor kan korrigeres ved å avinstallere og installere nydelig suppe.

Installere en parser

Før du diskuterer forskjellene mellom forskjellige parsers som du kan bruke med Beautiful Soup, la oss skrive koden for å lage en suppe.

fra bs4 import BeautifulSoup suppe = BeautifulSoup ("

Dette er ugyldig HTML

"," html.parser ")

De BeautifulSoup objektet kan godta to argumenter. Det første argumentet er selve oppslaget, og det andre argumentet er den parseren du vil bruke. De forskjellige parsers er: html.parser, LXML, og html5lib. De LXML parser har to versjoner, en HTML-parser og en XML-parser.

De html.parser er en innebygd parser, og det virker ikke så bra i eldre versjoner av Python. Du kan installere de andre parserne ved hjelp av følgende kommandoer:

$ pip installere lxml $ pip installere html5lib

De LXML parser er veldig rask og kan brukes til å raskt analysere gitt HTML. På den annen side, html5lib parser er veldig treg, men det er også ekstremt lindrende. Her er et eksempel på å bruke hver av disse parsers:

suppe = BeautifulSoup ("

Dette er ugyldig HTML

"," html.parser ") print (suppe) #

Dette er ugyldig HTML

suppe = BeautifulSoup ("

Dette er ugyldig HTML

"," lxml ") print (suppe) #

Dette er ugyldig HTML

suppe = BeautifulSoup ("

Dette er ugyldig HTML

"," xml ") print (suppe) # #

Dette er ugyldig HTML

suppe = BeautifulSoup ("

Dette er ugyldig HTML

"," html5lib ") print (suppe) #

Dette er ugyldig HTML

Forskjellene som er skissert av eksemplet ovenfor, gjelder bare når du analyserer ugyldig HTML. Imidlertid er det meste av HTML på nettet feil, og å vite disse forskjellene vil hjelpe deg med å feilsøke noen parsingfeil og bestemme hvilken parser du vil bruke i et prosjekt. Generelt, den LXML parser er et veldig godt valg.

Objekter i vakker suppe

Beautiful Soup analyserer det gjeldende HTML-dokumentet i et tre med Python-objekter. Det er fire hoved Python-objekter du trenger å vite om: stikkordNavigableStringBeautifulSoup, og Kommentar.

De stikkord objekt refererer til en faktisk XML- eller HTML-tag i dokumentet. Du kan få tilgang til navnet på en tagg ved hjelp av tag.name. Du kan også sette et navn til noe annet. Navneendringen vil være synlig i merkingen generert av Vakker suppe.

Du kan få tilgang til forskjellige attributter som klasse og id for en tagg ved hjelp av tag [ 'klasse'] og tag [ 'id'] henholdsvis. Du kan også få tilgang til hele ordboken for attributter ved hjelp av tag.attrs. Du kan også legge til, fjerne eller endre attributter for en etikett. Attributtene som et element er klasse som kan ta flere verdier, lagres som en liste.

Teksten i en tag er lagret som en NavigableString i vakker suppe. Den har noen nyttige metoder som replace_with ( "string") å erstatte teksten i en tagg. Du kan også konvertere a NavigableString å unicode strengen bruker unicode ().

Beautiful Soup lar deg også få tilgang til kommentarene på en nettside. Disse kommentarene lagres som en Kommentar objekt, som også i utgangspunktet er a NavigableString.

Du har allerede lært om BeautifulSoup objekt i forrige seksjon. Det brukes til å representere dokumentet som helhet. Siden det ikke er et faktisk objekt, har det ikke noe navn eller attributter.

Få tittelen, overskriftene og koblingene

Du kan ekstrahere sidetittelen og andre slike data veldig enkelt ved hjelp av Beautiful Soup. La oss skrape Wikipedia-siden om Python. Først må du oppnå markeringen av siden ved å bruke følgende kode basert på forespørselsmodulets veiledning for å få tilgang til nettsider.

importer forespørsler fra bs4 import BeautifulSoup req = requests.get ('https://en.wikipedia.org/wiki/Python_ (programming_language)') suppe = BeautifulSoup (req.text, "lxml")

Nå som du har opprettet suppen, kan du få tittelen på nettsiden ved hjelp av følgende kode:

suppe.title # Python (programmeringsspråk) - Wikipedia suppe.title.name # 'title' suppe.title.string # 'Python (programmeringsspråk) - Wikipedia'

Du kan også skrape nettsiden for annen informasjon som hovedoverskriften eller første ledd, deres klasser eller id Egenskap.

suppe.h1 # 

Python (programmeringsspråk)

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

Python - Programmeringsspråk

På samme måte kan du iterere gjennom alle koblingene eller underposisjonen i et dokument ved hjelp av følgende kode:

for sub_heading i soup.find_all ('h2'): print (sub_heading.text) # alle underrubrikkene som innhold, historie [rediger] ... 

Naviger DOM

Du kan navigere gjennom DOM-treet ved hjelp av vanlige merkenavn. Å kutte de taggenavnene kan hjelpe deg med å navigere i treet dypere. For eksempel kan du få den første lenken i første avsnitt av den oppgitte Wikipedia-siden ved å bruke soup.p.a. Alle koblingene i første ledd kan nås ved hjelp av soup.p.find_all ( 'a').

Du kan også få tilgang til alle barn av en tag som en liste ved å bruke tag.contents. For å få barna til en bestemt indeks, kan du bruke tag.contents [index]. Du kan også iterere over barnets barn ved å bruke .barn Egenskap.

Både .barn og .innhold er bare nyttige når du vil få tilgang til direktene eller første nivået av en tagg. For å få alle etterkommere, kan du bruke .etterkommere Egenskap.

print (suppe.p.contents) # [Python, 'er en mye brukt', ... den komplette listen] utskrift (suppe.p.contents [10]) # lesbarhet for barn i suppep.p.children: print (child.name) # b # None # a # None # a # Ingen # ... og så videre.

Du kan også få tilgang til foreldren til et element ved hjelp av .forelder Egenskap. På samme måte kan du få tilgang til alle forfedrene til et element ved hjelp av .foreldre Egenskap. Overordnet på toppnivå tag er BeautifulSoup Objektet selv, og dets forelder er Ingen.

skriv ut (suppe.parent.name) # div for foreldre i suppe.p.parents: print (parent.name) # div # div # div # body # html # [dokument]

Du kan få tilgang til forrige og neste søsken til et element ved hjelp av .previous_sibling og .next_sibling egenskaper. 

For at to elementer skal være søsken, bør de ha samme foreldre. Dette betyr at det første barnet av et element ikke vil ha en tidligere søsken. På samme måte vil det siste barnet av elementet ikke ha en neste søsken. I faktiske nettsider vil forrige og neste søsken av et element trolig være et nytt linjetegn. 

Du kan også iterere over alle søsken av et element ved hjelp av .previous_siblings og .next_siblings.

soup.head.next_sibling # '\ n' soup.p.a.next_sibling # 'for' soup.p.a.previous_sibling # 'er en mye brukt' print (suppe.p.

Du kan gå til elementet som kommer umiddelbart etter at det nåværende elementet bruker .next_element Egenskap. For å få tilgang til elementet som kommer umiddelbart før det nåværende elementet, bruk .previous_element Egenskap. 

På samme måte kan du iterere over alle elementene som kommer før og etter at det nåværende elementet bruker .previous_elements og .next_elements henholdsvis.

Siste tanker

Etter å ha fullført denne opplæringen, bør du nå ha en god forståelse av de viktigste forskjellene mellom ulike HTML-parsere. Du bør nå også kunne navigere gjennom en nettside og trekke ut viktige data. Dette kan være nyttig når du vil analysere alle overskrifter eller lenker på et gitt nettsted.

I neste del av serien lærer du hvordan du bruker Beautiful Soup-biblioteket til å søke og modifisere DOM.