Sopa hermosa - Codificación
Todos los documentos HTML o XML están escritos en alguna codificación específica como ASCII o UTF-8. Sin embargo, cuando carga ese documento HTML / XML en BeautifulSoup, se ha convertido a Unicode.
>>> markup = "<p>I will display £</p>"
>>> Bsoup = BeautifulSoup(markup)
>>> Bsoup.p
<p>I will display £</p>
>>> Bsoup.p.string
'I will display £'
El comportamiento anterior se debe a que BeautifulSoup utiliza internamente la sub-biblioteca llamada Unicode, Dammit para detectar la codificación de un documento y luego convertirlo a Unicode.
Sin embargo, no todo el tiempo, el Unicode, Dammit adivina correctamente. Como se busca en el documento byte a byte para adivinar la codificación, lleva mucho tiempo. Puede ahorrar algo de tiempo y evitar errores, si ya conoce la codificación pasándola al constructor de BeautifulSoup como from_encoding.
A continuación se muestra un ejemplo en el que BeautifulSoup identifica erróneamente un documento ISO-8859-8 como ISO-8859-7 -
>>> markup = b"<h1>\xed\xe5\xec\xf9</h1>"
>>> soup = BeautifulSoup(markup)
>>> soup.h1
<h1>νεμω</h1>
>>> soup.original_encoding
'ISO-8859-7'
>>>
Para resolver el problema anterior, páselo a BeautifulSoup usando from_encoding -
>>> soup = BeautifulSoup(markup, from_encoding="iso-8859-8")
>>> soup.h1
<h1>ולש </h1>
>>> soup.original_encoding
'iso-8859-8'
>>>
Otra característica nueva agregada de BeautifulSoup 4.4.0 es exclude_encoding. Se puede usar cuando no conoce la codificación correcta pero está seguro de que Unicode, maldita sea, muestra un resultado incorrecto.
>>> soup = BeautifulSoup(markup, exclude_encodings=["ISO-8859-7"])
Codificación de salida
La salida de un BeautifulSoup es un documento UTF-8, independientemente del documento introducido en BeautifulSoup. Debajo de un documento, donde están los caracteres polacos en 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>
En el ejemplo anterior, si observa, la etiqueta <meta> se ha reescrito para reflejar que el documento generado por BeautifulSoup ahora está en formato UTF-8.
Si no desea la salida generada en UTF-8, puede asignar la codificación deseada en 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'
En el ejemplo anterior, hemos codificado el documento completo, sin embargo, puede codificar cualquier elemento en particular en la sopa como si fuera una cadena de Python -
>>> soup.p.encode("latin-1")
b'<p>0My first paragraph.</p>'
>>> soup.h1.encode("latin-1")
b'<h1>My First Heading</h1>'
Cualquier carácter que no se pueda representar en la codificación elegida se convertirá en referencias numéricas de entidad XML. A continuación se muestra uno de esos ejemplos:
>>> 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>'
Si intenta codificar lo anterior en "latin-1" o "ascii", generará "☃", lo que indica que no hay representación para eso.
>>> print (tag.encode("latin-1"))
b'<b>☃</b>'
>>> print (tag.encode("ascii"))
b'<b>☃</b>'
Unicode, maldita sea
Unicode, Dammit se usa principalmente cuando el documento entrante está en formato desconocido (principalmente en un idioma extranjero) y queremos codificar en algún formato conocido (Unicode) y tampoco necesitamos Beautifulsoup para hacer todo esto.