python - 如何使用 BeautifulSoup 将 UTF-8 编码的 HTML 正确解析为 Unicode 字符串?

标签 python unicode utf-8 beautifulsoup urllib2

我正在运行一个获取 UTF-8 编码网页的 Python 程序,并使用 BeautifulSoup 从 HTML 中提取一些文本。

但是,当我将此文本写入文件(或在控制台上打印)时,它会以意外的编码写入。

示例程序:

import urllib2
from BeautifulSoup import BeautifulSoup

# Fetch URL
url = 'http://www.voxnow.de/'
request = urllib2.Request(url)
request.add_header('Accept-Encoding', 'utf-8')

# Response has UTF-8 charset header,
# and HTML body which is UTF-8 encoded
response = urllib2.urlopen(request)

# Parse with BeautifulSoup
soup = BeautifulSoup(response)

# Print title attribute of a <div> which uses umlauts (e.g. können)
print repr(soup.find('div', id='navbutton_account')['title'])

运行它会给出结果:

# u'Hier k\u0102\u015bnnen Sie sich kostenlos registrieren und / oder einloggen!'

但我希望 Python Unicode 字符串将 können 字中的 ö 呈现为 \xf6 :

# u'Hier k\xf6bnnen Sie sich kostenlos registrieren und / oder einloggen!'

我尝试将'fromEncoding'参数传递给BeautifulSoup,并尝试read()decode() response对象,但它要么没有区别,要么引发错误。

使用命令 curl www.voxnow.de | hexdump -C,我可以看到网页对于 ö 字符确实是 UTF-8 编码的(即它包含 0xc3 0xb6):

      20 74 69 74 6c 65 3d 22  48 69 65 72 20 6b c3 b6  | title="Hier k..|
      6e 6e 65 6e 20 53 69 65  20 73 69 63 68 20 6b 6f  |nnen Sie sich ko|
      73 74 65 6e 6c 6f 73 20  72 65 67 69 73 74 72 69  |stenlos registri|

我已经超出了我的 Python 能力的极限,所以我不知道如何进一步调试它。有什么建议吗?

最佳答案

正如上面提到的一半,我的问题本质上是 this question 的副本。

HTML 内容将自身报告为 UTF-8 编码,并且大部分情况下是这样,除了一两个流氓无效 UTF-8 字符。

这显然使 BeautifulSoup 混淆了正在使用哪种编码,以及在将内容传递给 BeautifulSoup 时尝试首先解码为 UTF-8 时,例如 这个:

soup = BeautifulSoup(response.read().decode('utf-8'))

我会得到错误:

UnicodeDecodeError: 'utf8' codec can't decode bytes in position 186812-186813: 
                    invalid continuation byte

更仔细地查看输出,有一个字符 Ü 的实例被错误地编码为无效字节序列 0xe3 0x9c,而不是正确的 0xc3 0x9c

正如该问题当前的 highest-rated answer 所暗示的,可以在解析时删除无效的 UTF-8 字符,以便仅将有效数据传递给 BeautifulSoup:

soup = BeautifulSoup(response.read().decode('utf-8', 'ignore'))

关于python - 如何使用 BeautifulSoup 将 UTF-8 编码的 HTML 正确解析为 Unicode 字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20205455/

相关文章:

python - bool() 在 Python 中的实际应用是什么?

python - 是否有任何 python 包可以很好地从 RTL 语言的 PDF 中提取文本?

python - 添加到购物车时 selenium 失败,如何单击 javascript 按钮?

mysql - php mb_detect_encoding 在 mysql 中等效

objective-c - Objective C 中 unicode 字符的数值

C# StreamReader Encoding.UTF8 不工作

php - 一些主机不喜欢设置名称 utf8 -- "Cannot execute queries while other unbuffered queries are active."

python - 理解一个 super 简单的函数输出

php - 联系表单电子邮件中主题的 UTF-8 编码

PHP json_encode 对单词中的重音进行编码