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.
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:
ImportError
oppstår når du kjører Python 2-versjonen av koden under Python 3.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.
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.
Beautiful Soup analyserer det gjeldende HTML-dokumentet i et tre med Python-objekter. Det er fire hoved Python-objekter du trenger å vite om: stikkord
, NavigableString
, BeautifulSoup
, 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.
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] ...
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.
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.