Beautiful Soup - Codifica

Tutti i documenti HTML o XML sono scritti in una codifica specifica come ASCII o UTF-8. Tuttavia, quando carichi quel documento HTML / XML in BeautifulSoup, è stato convertito in Unicode.

>>> markup = "<p>I will display £</p>"
>>> Bsoup = BeautifulSoup(markup)
>>> Bsoup.p
<p>I will display £</p>
>>> Bsoup.p.string
'I will display £'

Il comportamento sopra è dovuto al fatto che BeautifulSoup utilizza internamente la sotto-libreria chiamata Unicode, Dammit per rilevare la codifica di un documento e quindi convertirla in Unicode.

Tuttavia, non sempre, Unicode, Dammit indovina correttamente. Poiché il documento viene cercato byte per byte per indovinare la codifica, ci vuole molto tempo. Puoi risparmiare tempo ed evitare errori, se conosci già la codifica passandola al costruttore BeautifulSoup come from_encoding.

Di seguito è riportato un esempio in cui BeautifulSoup identifica erroneamente un documento ISO-8859-8 come ISO-8859-7 -

>>> markup = b"<h1>\xed\xe5\xec\xf9</h1>"
>>> soup = BeautifulSoup(markup)
>>> soup.h1
<h1>νεμω</h1>
>>> soup.original_encoding
'ISO-8859-7'
>>>

Per risolvere il problema precedente, passalo a BeautifulSoup usando from_encoding -

>>> soup = BeautifulSoup(markup, from_encoding="iso-8859-8")
>>> soup.h1
<h1>ולש </h1>
>>> soup.original_encoding
'iso-8859-8'
>>>

Un'altra nuova funzionalità aggiunta da BeautifulSoup 4.4.0 è exclude_encoding. Può essere utilizzato, quando non si conosce la codifica corretta ma si è sicuri che Unicode, Dammit sta mostrando un risultato sbagliato.

>>> soup = BeautifulSoup(markup, exclude_encodings=["ISO-8859-7"])

Codifica dell'output

L'output di BeautifulSoup è un documento UTF-8, indipendentemente dal documento inserito in BeautifulSoup. Di seguito un documento, dove i caratteri polacchi sono presenti nel formato ISO-8859-2.

html_markup = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-2">
</HEAD>
<BODY>
ą ć ę ł ń ó ś ź ż Ą Ć Ę Ł Ń Ó Ś Ź Ż
</BODY>
</HTML>
"""


>>> soup = BeautifulSoup(html_markup)
>>> print(soup.prettify())
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
   <head>
      <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
   </head>
   <body>
      ą ć ę ł ń ó ś ź ż Ą Ć Ę Ł Ń Ó Ś Ź Ż
   </body>
</html>

Nell'esempio sopra, se noti, il tag <meta> è stato riscritto per riflettere il documento generato da BeautifulSoup ora è in formato UTF-8.

Se non vuoi l'output generato in UTF-8, puoi assegnare la codifica desiderata in prettify ().

>>> print(soup.prettify("latin-1"))
b'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n<html>\n <head>\n <meta content="text/html; charset=latin-1" http-equiv="content-type"/>\n </head>\n <body>\n ą ć ę ł ń \xf3 ś ź ż Ą Ć Ę Ł Ń \xd3 Ś Ź Ż\n </body>\n</html>\n'

Nell'esempio sopra, abbiamo codificato il documento completo, tuttavia puoi codificare, qualsiasi elemento particolare nella zuppa come se fosse una stringa Python -

>>> soup.p.encode("latin-1")
b'<p>0My first paragraph.</p>'
>>> soup.h1.encode("latin-1")
b'<h1>My First Heading</h1>'

Tutti i caratteri che non possono essere rappresentati nella codifica scelta verranno convertiti in riferimenti numerici di entità XML. Di seguito è riportato uno di questi esempi:

>>> markup = u"<b>\N{SNOWMAN}</b>"
>>> snowman_soup = BeautifulSoup(markup)
>>> tag = snowman_soup.b
>>> print(tag.encode("utf-8"))
b'<b>\xe2\x98\x83</b>'

Se provi a codificare quanto sopra in "latin-1" o "ascii", verrà generato "☃", indicando che non c'è alcuna rappresentazione per questo.

>>> print (tag.encode("latin-1"))
b'<b>☃</b>'
>>> print (tag.encode("ascii"))
b'<b>☃</b>'

Unicode, dannazione

Unicode, Dammit viene utilizzato principalmente quando il documento in arrivo è in formato sconosciuto (principalmente lingua straniera) e vogliamo codificare in un formato noto (Unicode) e inoltre non abbiamo bisogno di Beautifulsoup per fare tutto questo.