Beautiful Soup - Risoluzione dei problemi

Gestione degli errori

Esistono due tipi principali di errori che devono essere gestiti in BeautifulSoup. Questi due errori non provengono dal tuo script ma dalla struttura dello snippet perché l'API BeautifulSoup genera un errore.

I due errori principali sono i seguenti:

AttributeError

È causato quando la notazione del punto non trova un tag di pari livello nel tag HTML corrente. Ad esempio, potresti aver riscontrato questo errore, a causa della mancanza del "tag di ancoraggio", cost-key genererà un errore mentre attraversa e richiede un tag di ancoraggio.

KeyError

Questo errore si verifica se l'attributo del tag HTML richiesto è mancante. Ad esempio, se non abbiamo l'attributo data-pid in uno snippet, la chiave pid genererà un errore di chiave.

Per evitare i due errori sopra elencati durante l'analisi di un risultato, tale risultato verrà ignorato per assicurarsi che uno snippet non valido non venga inserito nei database -

except(AttributeError, KeyError) as er:
pass

diagnosticare()

Ogni volta che troviamo difficoltà nel capire cosa fa BeautifulSoup al nostro documento o HTML, passalo semplicemente alla funzione diagnostic (). Passando il file del documento alla funzione diagnostic (), possiamo mostrare come l'elenco dei diversi parser gestisce il documento.

Di seguito è riportato un esempio per dimostrare l'uso della funzione diagnostic ():

from bs4.diagnose import diagnose

with open("20 Books.html",encoding="utf8") as fp:
   data = fp.read()
   
diagnose(data)

Produzione

Errore di analisi

Esistono due tipi principali di errori di analisi. Potresti ottenere un'eccezione come HTMLParseError, quando inserisci il tuo documento in BeautifulSoup. Potresti anche ottenere un risultato imprevisto, dove l'albero di analisi di BeautifulSoup ha un aspetto molto diverso dal risultato atteso dal documento di analisi.

Nessuno degli errori di analisi è causato da BeautifulSoup. È a causa del parser esterno che utilizziamo (html5lib, lxml) poiché BeautifulSoup non contiene alcun codice del parser. Un modo per risolvere l'errore di analisi precedente è utilizzare un altro parser.

from HTMLParser import HTMLParser

try:
   from HTMLParser import HTMLParseError
except ImportError, e:
   # From python 3.5, HTMLParseError is removed. Since it can never be
   # thrown in 3.5, we can just define our own class as a placeholder.
   class HTMLParseError(Exception):
      pass

Il parser HTML integrato in Python causa due errori di analisi più comuni, HTMLParser.HTMLParserError: tag di inizio non valido e HTMLParser.HTMLParserError: tag di fine errato e per risolvere questo problema, è utilizzare principalmente un altro parser: lxml o html5lib.

Un altro tipo comune di comportamento imprevisto è che non riesci a trovare un tag che sai essere nel documento. Tuttavia, quando si esegue find_all () restituisce [] o find () restituisce None.

Ciò potrebbe essere dovuto al parser HTML integrato in Python a volte salta i tag che non comprende.

Errore del parser XML

Per impostazione predefinita, il pacchetto BeautifulSoup analizza i documenti come HTML, tuttavia, è molto facile da usare e gestisce XML mal formato in modo molto elegante usando beautifulsoup4.

Per analizzare il documento come XML, devi avere un parser lxml e devi solo passare "xml" come secondo argomento al costruttore di Beautifulsoup -

soup = BeautifulSoup(markup, "lxml-xml")

o

soup = BeautifulSoup(markup, "xml")

Un errore di analisi XML comune è:

AttributeError: 'NoneType' object has no attribute 'attrib'

Ciò potrebbe accadere nel caso in cui qualche elemento sia mancante o non definito durante l'utilizzo della funzione find () o findall ().

Altri errori di analisi

Di seguito sono riportati alcuni degli altri errori di analisi di cui parleremo in questa sezione:

Problema ambientale

Oltre agli errori di analisi sopra menzionati, potresti riscontrare altri problemi di analisi come problemi ambientali in cui lo script potrebbe funzionare in un sistema operativo ma non in un altro sistema operativo o potrebbe funzionare in un ambiente virtuale ma non in un altro ambiente virtuale o potrebbe non funzionare fuori dall'ambiente virtuale. Tutti questi problemi possono essere dovuti al fatto che i due ambienti hanno diverse librerie di parser disponibili.

Si consiglia di conoscere o controllare il parser predefinito nell'ambiente di lavoro corrente. È possibile controllare il parser predefinito corrente disponibile per l'ambiente di lavoro corrente oppure passare esplicitamente la libreria del parser richiesta come secondi argomenti al costruttore BeautifulSoup.

Case-insensitive

Poiché i tag e gli attributi HTML non fanno distinzione tra maiuscole e minuscole, tutti e tre i parser HTML convertono i nomi di tag e attributi in lettere minuscole. Tuttavia, se si desidera conservare tag e attributi con lettere maiuscole o minuscole, è meglio analizzare il documento come XML.

UnicodeEncodeError

Esaminiamo il segmento di codice seguente:

soup = BeautifulSoup(response, "html.parser")
   print (soup)

Produzione

UnicodeEncodeError: 'charmap' codec can't encode character '\u011f'

Il problema sopra potrebbe essere dovuto a due situazioni principali. Potresti provare a stampare un carattere Unicode che la tua console non sa come visualizzare. Secondo, stai provando a scrivere su un file e passi un carattere Unicode che non è supportato dalla tua codifica predefinita.

Un modo per risolvere il problema precedente è codificare il testo / carattere della risposta prima di preparare la zuppa per ottenere il risultato desiderato, come segue:

responseTxt = response.text.encode('UTF-8')

KeyError: [attr]

È causato dall'accesso al tag ['attr'] quando il tag in questione non definisce l'attributo attr. Gli errori più comuni sono: "KeyError: 'href'" e "KeyError: 'class'". Usa tag.get ('attr') se non sei sicuro che attr sia definito.

for item in soup.fetch('a'):
   try:
      if (item['href'].startswith('/') or "tutorialspoint" in item['href']):
      (...)
   except KeyError:
      pass # or some other fallback action

AttributeError

Potresti incontrare AttributeError come segue:

AttributeError: 'list' object has no attribute 'find_all'

L'errore precedente si verifica principalmente perché ti aspettavi che find_all () restituisse un singolo tag o stringa. Tuttavia, soup.find_all restituisce un elenco di elementi Python.

Tutto quello che devi fare è scorrere l'elenco e catturare i dati da quegli elementi.