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

2024-09-30 20:34:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在运行一个Python程序,它获取一个UTF-8编码的web页面,并使用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中的ö呈现为^{}

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

我已经尝试过将'fromnoding'参数传递给BeautifulSoup,并尝试read()decode()对象,但它要么没有区别,要么抛出错误。

使用命令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能力的限制,所以对于如何进一步调试它,我不知所措。有什么建议吗?


Tags: 文本import程序url编码titlerequesthtml
2条回答

正如justhalf在上面指出的,我的问题本质上是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,而不是正确的^{}

正如目前关于这个问题的highest-rated answer所表明的,在解析时可以删除无效的UTF-8字符,这样只有有效的数据才能传递给BeautifulSoup:

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

将结果编码为utf-8似乎对我有效:

print (soup.find('div', id='navbutton_account')['title']).encode('utf-8')

它产生:

Hier können Sie sich kostenlos registrieren und / oder einloggen!

相关问题 更多 >