Beautiful Soup - 編碼



所有 HTML 或 XML 文件都以某種特定的編碼編寫,例如 ASCII 或 UTF-8。但是,當您將該 HTML/XML 文件載入到 BeautifulSoup 中時,它已轉換為 Unicode。

示例

from bs4 import BeautifulSoup
markup = "<p>I will display £</p>"
soup = BeautifulSoup(markup, "html.parser")
print (soup.p)
print (soup.p.string)

輸出

<p>I will display £</p>
I will display £

上述行為是因為 BeautifulSoup 內部使用名為 Unicode,Dammit 的子庫來檢測文件的編碼,然後將其轉換為 Unicode。

但是,並非所有時候,Unicode,Dammit 都能正確猜測。由於文件逐位元組搜尋以猜測編碼,因此需要大量時間。如果您已經知道編碼,可以透過將其作為 from_encoding 傳遞給 BeautifulSoup 建構函式,從而節省一些時間並避免錯誤。

下面是一個示例,其中 BeautifulSoup 將 ISO-8859-8 文件錯誤識別為 ISO-8859-7 −

示例

from bs4 import BeautifulSoup
markup = b"<h1>\xed\xe5\xec\xf9</h1>"
soup = BeautifulSoup(markup, 'html.parser')
print (soup.h1)

print (soup.original_encoding)

輸出

<h1>翴檛</h1>
ISO-8859-7

要解決上述問題,請使用 from_encoding 將其傳遞給 BeautifulSoup −

示例

from bs4 import BeautifulSoup
markup = b"<h1>\xed\xe5\xec\xf9</h1>"
soup = BeautifulSoup(markup, "html.parser", from_encoding="iso-8859-8")
print (soup.h1)

print (soup.original_encoding)

輸出

<h1>םולש</h1>
iso-8859-8

從 BeautifulSoup 4.4.0 開始新增的另一個新功能是 exclude_encoding。當您不知道正確的編碼,但確定 Unicode,Dammit 顯示的結果錯誤時,可以使用它。

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

輸出編碼

無論輸入到 BeautifulSoup 的文件是什麼,BeautifulSoup 的輸出都是 UTF-8 文件。下面是一個文件,其中波蘭語字元以 ISO-8859-2 格式存在。

示例

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

from bs4 import BeautifulSoup

soup = BeautifulSoup(markup, "html.parser", from_encoding="iso-8859-8")
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>

在上面的示例中,如果您注意到,<meta> 標籤已被重寫以反映從 BeautifulSoup 生成的文件現在為 UTF-8 格式。

如果您不希望生成的輸出為 UTF-8,可以在 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'

在上面的示例中,我們對整個文件進行了編碼,但是您可以對 soup 中的任何特定元素進行編碼,就像它們是 python 字串一樣 −

soup.p.encode("latin-1")
soup.h1.encode("latin-1")

輸出

b'<p>My first paragraph.</p>'
b'<h1>My First Heading</h1>'

任何在您選擇的編碼中無法表示的字元都將轉換為數字 XML 實體引用。下面是一個這樣的示例 −

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

如果您嘗試以“latin-1”或“ascii”編碼上述內容,它將生成“&#9731”,表示沒有該字元的表示形式。

print (tag.encode("latin-1"))
print (tag.encode("ascii"))

輸出

b'<b>☃</b>'
b'<b>☃</b>'

Unicode,Dammit

Unicode,Dammit 主要用於傳入文件格式未知(主要是外語)並且我們希望以某種已知格式(Unicode)進行編碼,並且我們不需要 Beautifulsoup 完成所有這些操作的情況。

廣告

© . All rights reserved.