Belle soupe - Encodage

Tous les documents HTML ou XML sont écrits dans un encodage spécifique comme ASCII ou UTF-8. Cependant, lorsque vous chargez ce document HTML / XML dans BeautifulSoup, il a été converti en Unicode.

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

Le comportement ci-dessus est dû au fait que BeautifulSoup utilise en interne la sous-bibliothèque appelée Unicode, Dammit pour détecter le codage d'un document, puis le convertir en Unicode.

Cependant, pas tout le temps, l'Unicode, Dammit devine correctement. Comme le document est recherché octet par octet pour deviner le codage, cela prend beaucoup de temps. Vous pouvez gagner du temps et éviter les erreurs, si vous connaissez déjà l'encodage en le passant au constructeur BeautifulSoup comme from_encoding.

Voici un exemple où le BeautifulSoup identifie à tort, un document ISO-8859-8 comme ISO-8859-7 -

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

Pour résoudre le problème ci-dessus, transmettez-le à BeautifulSoup à l'aide de from_encoding -

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

Une autre nouvelle fonctionnalité ajoutée à partir de BeautifulSoup 4.4.0 est, exclude_encoding. Il peut être utilisé lorsque vous ne connaissez pas le bon encodage mais que vous êtes sûr qu'Unicode, Dammit affiche un résultat incorrect.

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

Codage de sortie

La sortie d'un BeautifulSoup est un document UTF-8, quel que soit le document entré dans BeautifulSoup. Ci-dessous un document, où se trouvent les caractères polonais au format 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>

Dans l'exemple ci-dessus, si vous remarquez, la balise <meta> a été réécrite pour refléter le document généré par BeautifulSoup est maintenant au format UTF-8.

Si vous ne voulez pas la sortie générée en UTF-8, vous pouvez affecter l'encodage souhaité dans 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'

Dans l'exemple ci-dessus, nous avons encodé le document complet, mais vous pouvez encoder n'importe quel élément particulier de la soupe comme s'il s'agissait d'une chaîne python -

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

Tous les caractères qui ne peuvent pas être représentés dans l'encodage choisi seront convertis en références d'entités XML numériques. Voici un exemple de ce type -

>>> 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 vous essayez d'encoder ce qui précède en «latin-1» ou «ascii», il générera «☃», indiquant qu'il n'y a pas de représentation pour cela.

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

Unicode, bon sang

Unicode, Dammit est principalement utilisé lorsque le document entrant est dans un format inconnu (principalement une langue étrangère) et que nous voulons encoder dans un format connu (Unicode) et que nous n'avons pas besoin de Beautifulsoup pour faire tout cela.