Scraping Webpages in Python With Beautiful Soup The Basics

In un precedente tutorial, ti ho mostrato come usare il modulo Richieste per accedere alle pagine web usando Python. Il tutorial copriva molti argomenti come fare richieste GET / POST e scaricare cose come immagini o PDF a livello di programmazione. L'unica cosa che mancava da quel tutorial era una guida su come raschiare le pagine web a cui si accede usando Requests per estrarre le informazioni di cui si ha bisogno.

In questo tutorial imparerai su Beautiful Soup, che è una libreria Python per estrarre dati da file HTML. L'attenzione in questo tutorial sarà dedicata all'apprendimento delle basi della libreria e argomenti più avanzati saranno trattati nel prossimo tutorial. Si prega di notare che questo tutorial utilizza Beautiful Soup 4 per tutti gli esempi.

Installazione

Puoi installare Beautiful Soup 4 usando seme. Il nome del pacchetto è beautifulsoup4. Dovrebbe funzionare sia su Python 2 che su Python 3.

$ pip installa beautifulsoup4

Se non hai pip installato sul tuo sistema, puoi scaricare direttamente il tarball sorgente di Beautiful Soup 4 e installarlo usando setup.py.

$ python setup.py install

BeautifulSoup è originariamente confezionato come codice Python 2. Quando lo si installa per l'uso con Python 3, viene automaticamente aggiornato al codice Python 3. Il codice non verrà convertito a meno che non si installi il pacchetto. Ecco alcuni errori comuni che potresti notare:

  • Il "Nessun modulo chiamato HTMLParser" ImportError si verifica quando si esegue la versione Python 2 del codice in Python 3.
  • Il "Nessun modulo chiamato html.parser" ImportError si verifica quando si esegue la versione Python 3 del codice in Python 2.

Entrambi gli errori sopra possono essere corretti disinstallando e reinstallando Beautiful Soup.

Installazione di un parser

Prima di discutere le differenze tra i diversi parser che puoi usare con Beautiful Soup, scriviamo il codice per creare una zuppa.

da bs4 import BeautifulSoup soup = BeautifulSoup ("

Questo è HTML non valido

"," html.parser ")

Il BeautifulSoup l'oggetto può accettare due argomenti. Il primo argomento è il markup effettivo e il secondo argomento è il parser che si desidera utilizzare. I diversi parser sono: html.parser, lxml e html5lib. Il lxml parser ha due versioni, un parser HTML e un parser XML.

Il html.parser è un parser integrato e non funziona così bene nelle versioni precedenti di Python. È possibile installare gli altri parser utilizzando i seguenti comandi:

$ pip installa lxml $ pip installa html5lib

Il lxml parser è molto veloce e può essere utilizzato per analizzare rapidamente dato HTML. D'altra parte, il html5lib parser è molto lento, ma è anche estremamente indulgente. Ecco un esempio di utilizzo di ciascuno di questi parser:

soup = BeautifulSoup ("

Questo è HTML non valido

"," html.parser ") stampa (zuppa) #

Questo è HTML non valido

soup = BeautifulSoup ("

Questo è HTML non valido

"," lxml ") stampa (zuppa) #

Questo è HTML non valido

soup = BeautifulSoup ("

Questo è HTML non valido

"," xml ") stampa (zuppa) # #

Questo è HTML non valido

soup = BeautifulSoup ("

Questo è HTML non valido

"," html5lib ") stampa (zuppa) #

Questo è HTML non valido

Le differenze delineate nell'esempio precedente sono importanti solo quando si analizza l'HTML non valido. Tuttavia, la maggior parte dell'HTML sul Web è malformata e conoscere queste differenze ti aiuterà a eseguire il debug di alcuni errori di analisi e decidere quale parser vuoi utilizzare in un progetto. In generale, il lxml parser è un'ottima scelta.

Oggetti nella bella zuppa

Beautiful Soup analizza il dato documento HTML in un albero di oggetti Python. Esistono quattro oggetti Python principali che è necessario conoscere: EtichettaNavigableStringBeautifulSoup, e Commento.

Il Etichetta oggetto si riferisce a un tag XML o HTML effettivo nel documento. Puoi accedere al nome di un tag usando tag.name. Puoi anche impostare il nome di un tag su qualcos'altro. La modifica del nome sarà visibile nel markup generato da Beautiful Soup.

Puoi accedere a diversi attributi come la classe e l'ID di un tag usando [ 'Classe'] tag e tag [ 'id'] rispettivamente. Puoi anche accedere all'intero dizionario di attributi usando tag.attrs. Puoi anche aggiungere, rimuovere o modificare gli attributi di un tag. Gli attributi come quelli di un elemento classe che può assumere più valori sono memorizzati come una lista.

Il testo all'interno di un tag è memorizzato come NavigableString nella bella zuppa. Ha alcuni metodi utili come replace_with ( "stringa") per sostituire il testo all'interno di un tag. Puoi anche convertire a NavigableString per unicode stringa usando unicode ().

Beautiful Soup ti permette anche di accedere ai commenti in una pagina web. Questi commenti sono memorizzati come Commento oggetto, che è anche fondamentalmente a NavigableString.

Hai già imparato a conoscere il BeautifulSoup oggetto nella sezione precedente. È usato per rappresentare il documento nel suo insieme. Dal momento che non è un oggetto reale, non ha alcun nome o attributi.

Ottenere il titolo, i titoli e i collegamenti

Puoi estrarre facilmente il titolo della pagina e altri dati simili usando Beautiful Soup. Analizziamo la pagina di Wikipedia su Python. Innanzitutto, dovrai ottenere il markup della pagina utilizzando il seguente codice basato sul tutorial del modulo Richieste per accedere alle pagine web.

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

Ora che hai creato la zuppa, puoi ottenere il titolo della pagina web usando il seguente codice:

soup.title # Python (linguaggio di programmazione) - Wikipedia soup.title.name # 'title' soup.title.string # 'Python (linguaggio di programmazione) - Wikipedia'

Puoi anche raschiare la pagina web per altre informazioni come l'intestazione principale o il primo paragrafo, le loro classi o il id attributo.

soup.h1 # 

Python (linguaggio di programmazione)

soup.h1.string # 'Python (linguaggio di programmazione)' 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 - Linguaggio di programmazione

Allo stesso modo, puoi scorrere tutti i link o sottotitoli in un documento usando il seguente codice:

per sottotitoli in soup.find_all ('h2'): print (sub_heading.text) # tutti i sottotitoli come Contenuto, Cronologia [modifica] ... 

Navigazione nel DOM

Puoi navigare attraverso l'albero DOM usando nomi di tag regolari. Concatenare questi nomi di tag può aiutarti a navigare l'albero più profondamente. Ad esempio, è possibile ottenere il primo collegamento nel primo paragrafo della pagina Wikipedia fornita utilizzando soup.p.a. È possibile accedere a tutti i collegamenti nel primo paragrafo utilizzando soup.p.find_all ( 'a').

Puoi anche accedere a tutti i figli di un tag come elenco usando tag.contents. Puoi usare i bambini per ottenere un indice specifico tag.contents [indice]. Puoi anche scorrere i figli di un tag usando il .bambini attributo.

Tutti e due .bambini e .contenuto sono utili solo quando vuoi accedere ai discendenti diretti o di primo livello di un tag. Per ottenere tutti i discendenti, puoi usare il .discendenti attributo.

print (soup.p.contents) # [Pitone, 'è ampiamente usato', ... la lista completa] print (soup.p.contents [10]) # readability per child in soup.p.children: print (child.name) # b # None # a # None # a # Nessuno # ... e così via.

Puoi anche accedere al genitore di un elemento usando il .genitore attributo. Allo stesso modo, puoi accedere a tutti gli antenati di un elemento usando il .genitori attributo. Il genitore del livello più alto il tag è il BeautifulSoup Oggetto stesso e il suo genitore è Nessuno.

print (soup.p.parent.name) # div per genitore in soup.p.parents: print (genitore.nome) # div # div # div # corpo # html # [documento]

Puoi accedere al fratello precedente e successivo di un elemento usando il .previous_sibling e .next_sibling attributi. 

Perché due elementi siano fratelli, dovrebbero avere lo stesso genitore. Ciò significa che il primo figlio di un elemento non avrà un fratello precedente. Allo stesso modo, l'ultimo figlio dell'elemento non avrà un fratello successivo. Nelle pagine Web effettive, i fratelli precedenti e successivi di un elemento saranno probabilmente un nuovo carattere di linea. 

È inoltre possibile eseguire l'iterazione su tutti i fratelli di un elemento utilizzando .previous_siblings e .next_siblings.

soup.head.next_sibling # '\ n' soup.p.a.next_sibling # 'per' soup.p.a.previous_sibling # 'è una stampa ampiamente usata (soup.p.b.previous_sibling) # None

Puoi andare all'elemento che viene immediatamente dopo l'elemento corrente usando il .next_element attributo. Per accedere all'elemento che viene immediatamente prima dell'elemento corrente, usa il .previous_element attributo. 

Allo stesso modo, puoi scorrere tutti gli elementi che precedono e seguono l'utilizzo dell'elemento corrente .previous_elements e .next_elements rispettivamente.

Pensieri finali

Dopo aver completato questo tutorial, ora dovresti avere una buona comprensione delle principali differenze tra i diversi parser HTML. Ora dovresti anche essere in grado di navigare attraverso una pagina Web ed estrarre dati importanti. Questo può essere utile quando si desidera analizzare tutte le intestazioni o collegamenti su un determinato sito web.

Nella parte successiva della serie, imparerai come utilizzare la libreria Beautiful Soup per cercare e modificare il DOM.