Beautiful Soup 与字符编码

4 投票
2 回答
3439 浏览
提问于 2025-04-16 23:31

我正在尝试用Beautiful Soup和Python 2.6.5从一个网站提取带有斯堪的纳维亚字符的文本和HTML。

html = open('page.html', 'r').read()
soup = BeautifulSoup(html)

descriptions = soup.findAll(attrs={'class' : 'description' })

for i in descriptions:
    description_html = i.a.__str__()
    description_text = i.a.text.__str__()
    description_html = description_html.replace("/subdir/", "http://www.domain.com/subdir/")
    print description_html

但是当我运行程序时,它出现了以下错误信息:

Traceback (most recent call last):
    File "test01.py", line 40, in <module>
        description_text = i.a.text.__str__()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 19:         ordinal not in range(128)

输入的页面似乎是用ISO-8859-1编码的,如果这能帮上忙的话。我试着用BeautifulSoup(html, fromEncoding="latin-1")来设置正确的源编码,但也没有解决问题。

现在是2011年,我还在为一些简单的字符编码问题苦恼,我相信这一切应该有一个非常简单的解决办法。

2 个回答

0

我之前也遇到过同样的问题,使用Beautiful Soup时,输出包含德语字符的文本失败了。可惜的是,网上有很多答案,包括StackOverflow上的,但都没有解决我的问题。

        title = str(link.contents[0].string)  

这让我遇到了'UnicodeEncodeError: 'ascii codec can't encode character u'\xe4' in position 32: ordinal not in range(128)'的错误。

虽然很多答案提供了一些有用的解决思路,但并没有完全解决我的问题。正如Lennart Regebro在这个链接中所说的:

当你使用str(u'\u2013')时,其实是在尝试把Unicode字符串转换成8位字符串。为了做到这一点,你需要使用一种编码方式,也就是把Unicode数据映射到8位数据。str()这个函数会使用系统默认的编码方式,而在Python 2中,这个默认编码是ASCII。ASCII只包含Unicode的前127个字符,也就是从\u0000到\u007F。因此,你会遇到上面的错误,因为ASCII编码根本不知道\u2013是什么(顺便说一下,它是一个长破折号)。

对我来说,问题很简单,就是没有使用str()把Beautiful Soup对象转换成字符串格式。调整控制台的默认输出也没有任何帮助。

            ### title = str(link.contents[0].string)
            ### should be
            title = link.contents[0].encode('utf-8')
5
i.a.__str__('latin-1')

或者

i.a.text.encode('latin-1')

应该可以正常工作。

你确定是 latin-1 吗?它应该能正确识别编码。

另外,如果你不需要指定编码,为什么不直接用 str(i.a) 呢?

编辑:看起来你需要 安装 chardet,这样它才能自动识别编码。

撰写回答