当前位置: 首页 > 面试题库 >

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

孙项禹
2023-03-14
问题内容

我正在运行一个Python程序,该程序可获取UTF-8编码的网页,并使用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的能力极限,因此对于如何进一步调试它一无所知。有什么建议吗?


问题答案:

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

正如该问题当前评分最高的答案所暗示的那样,在解析时可以删除无效的UTF-8字符,以便仅将有效数据传递给BeautifulSoup:

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


 类似资料:
  • 问题内容: PHP中是否有一个函数可以解码Unicode转义序列,例如“ ”到“ ”以及所有其他类似的事件? 我在这里找到了类似的问题,但似乎没有用。 问题答案: 尝试这个: 如果是基于UTF-16的C / C ++ / Java / Json风格:

  • 问题内容: 我有一个带有“ñ”字符的字符串,并且我有一些问题。我需要将此字符串编码为UTF-8编码。我已经通过这种方式尝试过,但是没有用: 如何将该字符串编码为utf-8? 问题答案: Java中的对象使用无法修改的UTF-16编码。 唯一可以使用不同编码的是。因此,如果你需要UTF-8数据,则需要一个。如果你有一个包含意外数据的,则问题出在较早的地方,该错误地将一些二进制数据错误地转换为a (即

  • 我正在为一位位于巴西的客户开发一个网站。他的网站的一部分显示了用户的反馈/评论。 以下是一个例子: 正确版本: “这是我的一分钟!” 当我向用户输出时,显示如下内容: 不正确的版本: “这是我的一分钟!” 我将这些评论保存到mySQL数据库(Hostgator),并将数据库排序规则设置为“utf8\U unicode\U ci”。 在超文本标记语言的顶部,我声明了以下内容: 我使用Laravel

  • 问题内容: 我正在使用Javascript 函数解码base64编码的字符串(特别是来自GitHubAPI的base64编码的内容)。问题是我回来了ASCII编码的字符(而不是)。如何正确处理传入的以base64编码的流,以便将其解码为utf-8? 问题答案: 此问题: “ Unicode问题”由于s是16位编码的字符串,因此在大多数浏览器中,如果字符超出8位字节的范围(0x00〜0xFF),则调

  • 我正在使用Javascript函数来解码一个base64编码的字符串(特别是GitHub API中base64编码的内容)。问题是我得到了ASCII编码的字符(像而不是)。如何正确处理传入的base64编码的流,以便将其解码为UTF-8?

  • 我正在处理一个位置数据集,其中一些位置名称使用本地字符。大多数字符都被正确地看到,但我对一些罗马尼亚字符有意见,比如“ș”。 我尝试改变我的Windows 10 64位系统区域设置使用UTF-8编码,但这并没有解决问题。 可以在此处找到用于测试的示例文件:https://drive.google.com/file/d/1T7QQQ7G_dA_rXD9Ewf51uuQ6CUkscjP_/view?u