【问题标题】:Python scraping gives unicode errorPython 抓取给出 unicode 错误
【发布时间】:2014-09-29 16:05:09
【问题描述】:
res = requests.get(self.urlBase)
soup = BeautifulSoup(html)
print soup.prettify()

给出错误:

'ascii' 编解码器无法对位置 10816 中的字符 u'\xa0' 进行编码: 序数不在范围内(128)

我正在使用 Requests 和 BeautifulSoup4。

我认为它与 unicode 有关?我看到的每个示例都以这种方式使用它而没有问题。不知道为什么我的编码有问题?

内容类型为text/html; charset=UTF-8

【问题讨论】:

  • 显示完整的回溯。
  • 你有一个编码错误;您很可能遇到print 的问题,而不是 BeautifulSoup。您是在此处重定向输出还是使用 IDE 控制台?
  • 你能给出一个会导致错误的示例 url 或 html 吗?
  • 另外,您将回复存储在res,但不要告诉我们您从哪里获得html
  • PrintFails。您的抓取很好,但是从使用 C 标准库 IO 的 Python 等应用程序将 Unicode 打印到 Windows 控制台是行不通的。

标签: python unicode web-scraping python-requests


【解决方案1】:
print soup.prettify().encode('utf8')

虽然在汤更好之前转储内容以从响应本身查看:

res = requests.get('urlfoobar')
print res.content

【讨论】:

    【解决方案2】:

    你说得对,这与 Unicode 有关,本质上,这是说它不能直接将某些字符打印到命令行,因为字符 '\xa0' 是拉丁语不间断空格, 显然。要解决此特定问题,请参阅this link

    编辑:请参阅下面的 cmets,了解有关打印模块的更多具体信息,以及对可能导致问题的原因的更彻底和完整的描述。

    编辑: This link 提到了相同的错误,并且在评论中提到 'ascii' codec 错误是 Python 2.x 独有的,来自请求和其他 urllib 模块。这证实了我之前的说法,尽管没有详尽的记录。

    现在提供一些不请自来的建议: 如果这涉及的程序很小并且没有很多依赖项或使用仅存在于 Python 2 中的库,使用 Python 3。 我今年夏天早些时候开始编写网络抓取项目并开始使用 Python 编写2.7,最终得到了几个我最终无法解决的涉及Unicode解码的错误,即使我使用了字符串本身的解码模块。

    然后我偶然发现 Python 3 实际上是专门为修复 Guido van Rossum 自己所说的“破坏 Python”而设计的——一劳永逸地将 Unicode 和字符串结合在一起。

    我问你的代码是否相对较小的原因——我实际上在几分钟内将我的整个脚本(大约 400 行)升级到了 Python 3——特别是因为我有一个很好的解释器,它告诉我语法问题会出现。有一些差异,但不是很多,你会很高兴你这样做了。

    短期修复:使用 Python 2 对 Unicode 的(有限)支持。

    长期修复:找到移植到 Python 3 的方法。

    编辑:因为这段代码专门引用了打印模块,所以我撤回了我的声明,因为我在打印模块方面没有足够的具体经验来制作 Python 2.x 和 3.x 中的测试用例,说明切换到Python 3 必然会解决这个问题。 但是,值得 OP 回复,看看问题是否得到解决。

    编辑 2:为了进一步使事情变得更不确定,我在 Python 2.7 和 Python 3.4 中尝试了以下代码:

    Python 2.7:

    from bs4 import BeautifulSoup
    soup = BeautifulSoup(u'string with "\xa0" character')
    print soup.prettify()
    

    Python 3.4:

    from bs4 import BeautifulSoup
    soup = BeautifulSoup('string with "\xa0" character')
    print(soup.prettify())
    

    两种方式都返回相同的预期答案。即使从字符串中删除 Unicode 分类器也不会影响 Python 2.7 的输出。需要进一步调查。

    【讨论】:

    • BeautifulSoup 默认为您提供 Unicode 输出;这里的问题出在环境中,Python 无法确定环境需要什么编码,或者已经确定 ASCII 是该环境的正确编解码器。 Python 3 的唯一区别是可能会选择一个不同的默认值,这同样可能是错误的。
    • 如果没有来自 OP 的更多上下文,我们不知道是哪一行产生了问题,也不知道正在使用哪个终端、控制台或 IDE,或者是否使用了对文件的重定向.换句话说,切换到 Python 3 在这里不一定有帮助。
    • 不是这样。 Python 3 仍然必须将 unicode 字符串编码为字节字符串以在控制台上显示,因为对于 stdio 应用程序来说,控制台/标准输出流是字节流。因此 Python 2 的所有 PrintFails 问题在 Python 3 中仍然存在。
    • 字符串类型在 Python 2 和 Python 3 之间的转换被深深地误解了。您仍然像以前一样拥有字节字符串和 unicode 字符串;不同之处在于(1)它们的命名不同(str/unicode -> bytes/str),(2)默认字符串文字为您提供 unicode 字符串,(3)更多库接口在本质上不是基于字节的地方使用 unicode 字符串,并且 (4) Python 为您在字节和 unicode 之间隐式转换的地方较少,可能会出错。
    • @punyidea:不,你误解了 Python 3 如何处理文本。正如我所说,BeautifulSoup 正确处理 Unicode。 Python 3 仍然有字节类型,打印到控制台 still 需要将 Unicode 字符串编码为字节。如果控制台声称它使用 ASCII 作为编解码器,那么这在 Python 3 中同样会失败。
    【解决方案3】:

    试试

    打印soup.decode('utf-8', 'ignore').prettify()

    这将忽略它无法理解的所有字符来解析汤字符串

    如果不选择'ignore'参数,遇到非ascii字符会报错

    【讨论】:

    • OP 有一个编码错误,而不是解码问题。
    • 假设它是 BeautifulSoup 是很自然的,因为 OP 不包含回溯。但是错误消息同样具有启发性。
    • 谢谢,很接近;我不得不encode它显然
    猜你喜欢
    • 1970-01-01
    • 2014-04-06
    • 2017-01-28
    • 1970-01-01
    • 2018-12-01
    • 2011-04-18
    • 2016-05-27
    • 2015-11-21
    • 2018-06-13
    相关资源
    最近更新 更多