Beautiful Soup - Mã hóa

Tất cả các tài liệu HTML hoặc XML được viết bằng một số mã hóa cụ thể như ASCII hoặc UTF-8. Tuy nhiên, khi bạn tải tài liệu HTML / XML đó vào BeautifulSoup, nó đã được chuyển đổi sang Unicode.

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

Hành vi trên là do BeautifulSoup sử dụng nội bộ thư viện con được gọi là Unicode, Dammit để phát hiện bảng mã của tài liệu và sau đó chuyển đổi nó thành Unicode.

Tuy nhiên, không phải lúc nào Unicode, Dammit cũng đoán đúng. Vì tài liệu được tìm kiếm từng byte để đoán mã hóa nên mất rất nhiều thời gian. Bạn có thể tiết kiệm một chút thời gian và tránh những sai lầm, nếu bạn đã biết mã hóa bằng cách chuyển nó tới hàm tạo BeautifulSoup dưới dạng from_encoding.

Dưới đây là một ví dụ mà BeautifulSoup xác định sai, tài liệu ISO-8859-8 là ISO-8859-7 -

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

Để giải quyết vấn đề trên, hãy chuyển nó cho BeautifulSoup bằng from_encoding -

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

Một tính năng mới khác được thêm vào từ BeautifulSoup 4.4.0 là, mã hóa loại trừ. Nó có thể được sử dụng, khi bạn không biết mã hóa chính xác nhưng chắc chắn rằng Unicode, Dammit đang hiển thị kết quả sai.

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

Mã hóa đầu ra

Đầu ra từ BeautifulSoup là tài liệu UTF-8, bất kể tài liệu đã nhập vào BeautifulSoup. Bên dưới tài liệu, nơi các ký tự đánh bóng ở định dạng 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>

Trong ví dụ trên, nếu bạn nhận thấy, thẻ <meta> đã được viết lại để phản ánh tài liệu được tạo từ BeautifulSoup hiện ở định dạng UTF-8.

Nếu bạn không muốn đầu ra được tạo trong UTF-8, bạn có thể chỉ định mã hóa mong muốn trong pretify ().

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

Trong ví dụ trên, chúng tôi đã mã hóa tài liệu hoàn chỉnh, tuy nhiên bạn có thể mã hóa, bất kỳ phần tử cụ thể nào trong súp như thể chúng là một chuỗi python -

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

Bất kỳ ký tự nào không thể được biểu diễn trong bảng mã đã chọn của bạn sẽ được chuyển đổi thành các tham chiếu thực thể XML số. Dưới đây là một ví dụ như vậy -

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

Nếu bạn cố gắng mã hóa phần trên bằng “latin-1” hoặc “ascii”, nó sẽ tạo ra “☃”, cho biết không có đại diện nào cho điều đó.

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

Unicode, chết tiệt

Unicode, Dammit được sử dụng chủ yếu khi tài liệu đến có định dạng không xác định (chủ yếu là tiếng nước ngoài) và chúng tôi muốn mã hóa ở một số định dạng đã biết (Unicode) và chúng tôi cũng không cần Beautifulsoup để làm tất cả điều này.