Güzel Çorba - Kodlama

Tüm HTML veya XML belgeleri, ASCII veya UTF-8 gibi bazı özel kodlamalarda yazılır. Ancak, bu HTML / XML belgesini BeautifulSoup'a yüklediğinizde, Unicode'a dönüştürülmüştür.

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

Yukarıdaki davranış, BeautifulSoup'un bir belgenin kodlamasını algılamak ve sonra onu Unicode'a dönüştürmek için Unicode, Dammit adlı alt kitaplığı dahili olarak kullanmasıdır.

Ancak her zaman değil, Unicode, Dammit doğru tahmin ediyor. Belge, kodlamayı tahmin etmek için bayt bayt arandığında, çok zaman alır. Kodlamayı from_encoding olarak BeautifulSoup yapıcısına geçirerek zaten biliyorsanız, biraz zaman kazanabilir ve hatalardan kaçınabilirsiniz.

Aşağıda BeautifulSoup'un yanlış tanımladığı bir örnek var, bir ISO-8859-8 belgesi ISO-8859-7 olarak -

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

Yukarıdaki sorunu çözmek için from_encoding kullanarak BeautifulSoup'a iletin -

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

BeautifulSoup 4.4.0'dan eklenen bir başka yeni özellik ise, exclude_encoding'dir. Doğru kodlamayı bilmediğinizde ancak Unicode, Dammit'in yanlış sonuç gösterdiğinden emin olduğunuzda kullanılabilir.

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

Çıkış kodlaması

BeautifulSoup'un çıktısı, BeautifulSoup'a girilen belgeden bağımsız olarak UTF-8 belgesidir. Lehçe karakterlerinin ISO-8859-2 biçiminde olduğu bir belgenin altında.

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>

Yukarıdaki örnekte, <meta> etiketinin BeautifulSoup'tan oluşturulan belgeyi yansıtacak şekilde yeniden yazıldığını fark ederseniz artık UTF-8 biçiminde.

Üretilen çıktının UTF-8'de olmasını istemiyorsanız, istediğiniz kodlamayı prettify () içinde atayabilirsiniz.

>>> 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'

Yukarıdaki örnekte, belgenin tamamını kodladık, ancak çorbadaki herhangi bir öğeyi bir python dizesi gibi kodlayabilirsiniz -

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

Seçtiğiniz kodlamada temsil edilemeyen tüm karakterler, sayısal XML varlık referanslarına dönüştürülecektir. Aşağıda böyle bir örnek var -

>>> 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>'

Yukarıdakileri "latin-1" veya "ascii" olarak kodlamaya çalışırsanız, bunun için bir temsil olmadığını belirten "☃" üretecektir.

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

Unicode, Lanet olsun

Unicode, Dammit esas olarak gelen belge bilinmeyen formatta olduğunda (çoğunlukla yabancı dilde) ve bilinen bir formatta (Unicode) kodlamak istediğimizde kullanılır ve ayrıca tüm bunları yapmak için Beautifulsoup'a ihtiyacımız yoktur.