【问题标题】:TypeError: 'str' does not support the buffer interface in html2textTypeError: 'str' 不支持 html2text 中的缓冲区接口
【发布时间】:2016-08-20 23:53:09
【问题描述】:

我正在使用 python3 进行一些网络抓取。我想保存网页并使用以下代码将其转换为文本:

import urllib
import html2text
url='http://www.google.com'
page = urllib.request.urlopen(url)
html_content = page.read()
rendered_content = html2text.html2text(html_content)

但是当我运行代码时,它报告了一个类型错误:

  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/html2text-2016.4.2-py3.4.egg/html2text/__init__.py", line 127, in feed
    data = data.replace("</' + 'script>", "</ignore>")
TypeError: 'str' does not support the buffer interface

谁能告诉我如何处理这个错误?提前谢谢!

【问题讨论】:

  • page.read().encode('utf-8')?
  • 感谢您回答我的问题!我试过了,但它显示 AttributeError: 'bytes' object has no attribute 'encode'...
  • 对不起,应该解码。

标签: python python-3.x web-scraping typeerror


【解决方案1】:

urlopen 返回的流被 b 表示为字节流,作为引用字符串之前的第一个字符。如果你排除它,就像在附加的代码中一样,它似乎可以作为 html2txt 的输入。

import urllib
import html2text
url='http://www.google.com'
with urllib.request.urlopen(url) as page:
    html_content = page.read()
charset_encoding = page.info().get_content_charset()
rendered_content = html2text.html2text(str(html_content)[1:], charset_encoding)

使用有关编码的建议进行了修订。是的,这是一个 hack,但它可以运行。不使用 str() 意味着原来的 TypeError 问题仍然存在。

【讨论】:

  • 这不是解决这个问题的正确方法。使用 str() 并删除 b 只是将字节字符串包装在字符串包装器中 - 这是一个 hack。它并没有解决根本问题,即字符串中有字符 Python 不知道如何表示。尝试使用此代码的人最终会在以后遇到令人沮丧的编码/解码问题。
  • 非常感谢您回答我的问题!现在可以了!
【解决方案2】:

我花时间对此进行了调查,结果很容易解决。

为什么会出现此错误

问题是输入错误之一:当您调用page.read() 时,返回了一个字节字符串,而不是一个常规字符串。

Byte strings 是 Python 处理不熟悉的字符编码的方式:基本上原始文本中的字符不映射到 Unicode(Python 3 的默认字符编码)。

因为 Python 不知道要使用什么编码,所以 Python 使用原始字节来表示此类字符串——无论如何,这就是所有数据在内部表示的方式——并让程序员决定使用什么编码。

对这些字节字符串调用的常规字符串方法 -​​ 例如 replace()html2text 尝试使用 - 失败,因为字节字符串没有定义这些方法。

解决方案

html_content = page.read().decode('iso-8859-1')

Padraic Cunningham 在 cmets 中的解决方案本质上是正确的:您必须首先告诉 Python 使用哪种字符编码来尝试将这些字节映射到正确的字符集。

不幸的是,这个特定文本不使用 Unicode,因此要求它使用UTF-8 编码进行解码会引发错误。

要使用的正确 编码实际上包含在Content-Type 标头下的请求标头本身中 - 这是所有符合 HTTP 的服务器响应都保证提供的标准标头。

只需调用page.info().get_content_charset() 即可返回此标头的值,在本例中为iso-8859-1。从那里,您可以使用iso-8859-1 对其进行正确解码,以便常规工具对其进行正常操作。

更通用的解决方案

charset_encoding = page.info().get_content_charset()
html_content = page.read().decode(charset_encoding)

【讨论】:

  • 非常感谢! html2text 现在可以工作了!但现在我有另一个问题。当我尝试打印 render_content 时,它再次报告 unicode 编码错误。它说 UnicodeEncodeError: 'ascii' codec can't encode character '\xbb' in position 345: ordinal not in range(128).你能告诉我如何解决这个问题吗?
  • 我不知道“rendered_content”是什么。但错误很明显:不是“iso-8859-1”,而是试图用原始 ASCII 编码你的字符串。 ASCII 不适用于这些字符。最好将此问题作为一个单独的问题提出,这样会有更多的人解决这个问题。
猜你喜欢
  • 2011-07-25
  • 2014-08-09
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2016-11-21
相关资源
最近更新 更多