Bela Sopa - Codificação

Todos os documentos HTML ou XML são escritos em alguma codificação específica como ASCII ou UTF-8. No entanto, quando você carrega esse documento HTML / XML no BeautifulSoup, ele foi convertido para Unicode.

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

O comportamento acima é porque o BeautifulSoup usa internamente a sub-biblioteca chamada Unicode, Dammit, para detectar a codificação de um documento e depois convertê-lo em Unicode.

Porém, nem sempre, o Unicode, Dammit adivinha corretamente. Como o documento é pesquisado byte a byte para adivinhar a codificação, leva muito tempo. Você pode economizar tempo e evitar erros, se você já conhece a codificação, passando-a para o construtor BeautifulSoup como from_encoding.

Abaixo está um exemplo em que o BeautifulSoup identifica incorretamente um 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 o problema acima, passe para BeautifulSoup usando from_encoding -

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

Outro novo recurso adicionado do BeautifulSoup 4.4.0 é exclude_encoding. Pode ser usado, quando você não sabe a codificação correta, mas tem certeza de que Unicode, Dammit está mostrando resultado errado.

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

Codificação de saída

A saída de um BeautifulSoup é um documento UTF-8, independentemente do documento inserido no BeautifulSoup. Abaixo de um documento, onde os caracteres polidos estão no 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>

No exemplo acima, se você observar, a tag <meta> foi reescrita para refletir o documento gerado a partir do BeautifulSoup agora no formato UTF-8.

Se você não quiser a saída gerada em UTF-8, pode atribuir a codificação desejada em 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'

No exemplo acima, codificamos o documento completo, no entanto, você pode codificar qualquer elemento específico da sopa como se fosse uma string python -

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

Todos os caracteres que não podem ser representados na codificação escolhida serão convertidos em referências numéricas de entidade XML. Abaixo está um exemplo -

>>> 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 você tentar codificar o código acima em “latin-1” ou “ascii”, irá gerar “☃”, indicando que não há representação para isso.

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

Unicode, droga

Unicode, Dammit é usado principalmente quando o documento recebido está em um formato desconhecido (principalmente em idioma estrangeiro) e queremos codificar em algum formato conhecido (Unicode) e também não precisamos do Beautifulsoup para fazer tudo isso.