【问题标题】:how to use extract_links() to get url from a webpage encoding by 'gb2312'如何使用 extract_links() 从“gb2312”编码的网页中获取 url
【发布时间】:2018-08-16 15:33:36
【问题描述】:

环境:python 2.7 操作系统:ubuntu

我想从网页中提取一些链接,并在 scrapy shell 中对其进行测试 但我遇到 UnicodeError:

我的代码:

le = LinkExtractor()

le.extract_links(response)

错误:

UnicodeDecodeError: 'utf8' 编解码器无法在位置解码字节 0xcc 39: 无效的继续字节

在这个网页源代码中,我发现它的编码是'gb2312',所以我尝试:

print response.body.decode('gb2312') 可以打印所有的html

但是当:

le.extract_links(response.body.decode('gb2312')), 

有错误:

AttributeError: 'unicode' 对象没有属性 'text'

因为 extract_links 需要 htmlresponse 作为参数,但是 response.body response.text 返回 'byte' 和 'Unicode' 对象;

类型(响应)

结果:类'scrapy.http.response.html.HtmlResponse'

所以我不知道如何修复响应并从中提取链接; 有没有办法指定返回的响应是'utf-8'而不是'gb2312'

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/scrapy/linkextractors/lxmlhtml.py", line 128, in extract_links
    links = self._extract_links(doc, response.url, response.encoding, base_url)
  File "/usr/local/lib/python2.7/dist-packages/scrapy/linkextractors/__init__.py", line 109, in _extract_links
    return self.link_extractor._extract_links(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/scrapy/linkextractors/lxmlhtml.py", line 76, in _extract_links
    return self._deduplicate_if_needed(links)
  File "/usr/local/lib/python2.7/dist-packages/scrapy/linkextractors/lxmlhtml.py", line 91, in _deduplicate_if_needed
    return unique_list(links, key=self.link_key)
  File "/usr/local/lib/python2.7/dist-packages/scrapy/utils/python.py", line 78, in unique
    seenkey = key(item)
  File "/usr/local/lib/python2.7/dist-packages/scrapy/linkextractors/lxmlhtml.py", line 43, in <lambda>
    keep_fragments=True)
  File "/usr/local/lib/python2.7/dist-packages/w3lib/url.py", line 433, in canonicalize_url
    parse_url(url), encoding=encoding)
  File "/usr/local/lib/python2.7/dist-packages/w3lib/url.py", line 510, in parse_url
    return urlparse(to_unicode(url, encoding))
  File "/usr/local/lib/python2.7/dist-packages/w3lib/util.py", line 27, in to_unicode
    return text.decode(encoding, errors)
  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xcc in position 39: invalid continuation byte

【问题讨论】:

    标签: python scrapy codec


    【解决方案1】:

    我认为您应该能够像这样手动指定编码: response.replace(encoding='gb2312') 然后尝试将其传递给链接提取器。

    编辑:所以似乎scrapy未能在链接处理链的某处指定url编码(在w3lib.url.canonicalize_url我相信在执行重复数据删除时)。作为一种解决方法,您可以使用以下方法:

    resp = response.replace(encoding='utf8', body=response.text.encode('utf8'))
    

    【讨论】:

    • 谢谢..我尝试 le.extract_links(response.replace(encoding='gb2312')),但它有同样的问题,我在 scrapy shell 中测试它
    • @crydby,这很奇怪,你能提供一个发生这种情况的 url 吗?也许是 UnicodeDecodeError 之前的完整回溯?
    • ,谢谢,上面有 UnicodeDecodeErroe 之前的完整回溯。
    • 它有效,谢谢,我想我应该了解更多关于请求和 htmlresponse 的信息。
    【解决方案2】:

    w3lib.url.canonicalize_url 在此网页中无法正常工作,以及上述解决方法

    resp = response.replace(encoding='utf8', body=response.text.encode('utf8'))

    只能在scrapy shell中工作

    所以我们可以在spider中指定canonicalize=True

    像这样:

    LinkExtractor(canonicalize=True)
    

    但在scrapy文档中说,一般情况下,

    您正在使用 LinkExtractor 跟踪链接,这样可以更可靠地保留 默认canonicalize=False

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-30
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多