【问题标题】:Crawl non-latin domain with scrapy用scrapy爬取非拉丁域
【发布时间】:2016-01-01 16:23:13
【问题描述】:

我需要用scrapy抓取“.рф”域中的一些网站。 Url 的结构如下:“http://сайтдляпримера.рф”(此 url 不是真实的,例如给出)。当然,我尝试使用的网站可以通过浏览器访问。 我尝试使用start_urls 属性开始爬行,例如:

start_urls = ['http://сайтдляпримера.рф']

还有start_requests函数:

def start_requests(self):
    return [scrapy.Request("http://сайтдляпримера.рф/", callback=self._test)]

它们都没有按预期工作,我收到以下控制台消息:

2016-01-01 19:02:01 [scrapy] INFO: Spider opened
2016-01-01 19:02:01 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2016-01-01 19:02:01 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023
2016-01-01 19:02:01 [scrapy] DEBUG: Retrying <GET http://%D1%81%D0%B0%D0%B9%D1%82%D0%B4%D0%BB%D1%8F%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B0.%D1%80%D1%84> (failed 1 times): DNS lookup failed: address '%D1%81%D0%B0%D0%B9%D1%82%D0%B4%D0%BB%D1%8F%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B0.%D1%80%D1%84' not found: [Errno -2] Name or service not known.
2016-01-01 19:02:01 [scrapy] DEBUG: Retrying <GET http://%D1%81%D0%B0%D0%B9%D1%82%D0%B4%D0%BB%D1%8F%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B0.%D1%80%D1%84> (failed 2 times): DNS lookup failed: address '%D1%81%D0%B0%D0%B9%D1%82%D0%B4%D0%BB%D1%8F%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B0.%D1%80%D1%84' not found: [Errno -2] Name or service not known.
2016-01-01 19:02:01 [scrapy] DEBUG: Gave up retrying <GET http://%D1%81%D0%B0%D0%B9%D1%82%D0%B4%D0%BB%D1%8F%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B0.%D1%80%D1%84> (failed 3 times): DNS lookup failed: address '%D1%81%D0%B0%D0%B9%D1%82%D0%B4%D0%BB%D1%8F%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B0.%D1%80%D1%84' not found: [Errno -2] Name or service not known.
2016-01-01 19:02:01 [scrapy] ERROR: Error downloading <GET http://%D1%81%D0%B0%D0%B9%D1%82%D0%B4%D0%BB%D1%8F%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B0.%D1%80%D1%84>: DNS lookup failed: address '%D1%81%D0%B0%D0%B9%D1%82%D0%B4%D0%BB%D1%8F%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B0.%D1%80%D1%84' not found: [Errno -2] Name or service not known.
2016-01-01 19:02:01 [scrapy] INFO: Closing spider (finished)

*如果有问题,我需要在基于 Linux 的操作系统上使用 scrapy。

有什么解决办法吗?如果可能的话,我可以从_spider 文件中解决这个问题,因为我无权访问框架的存储库(那里没有修改任何处理 http 请求的内容)

【问题讨论】:

    标签: python url scrapy httprequest scrapy-spider


    【解决方案1】:

    在处理国际化域名 (IDN) 时,您需要使用 idna 对非 ascii 网址进行编码。然后,您需要将结果字节解码为 un​​icode 字符串。另请注意,构成协议名称('http://')的 url 的 ascii 子字符串应单独添加前缀,以免在进行 idna 编码时搞砸:

    'http://' + u'сайтдляпримера.рф'.encode('idna').decode('utf-8')
    

    有关更多详细信息,另请参阅this document

    【讨论】:

    • 收到错误exceptions.TypeError: must be unicode, not str,当我尝试执行"http://сайтдляпримера.рф".decode('utf-8').encode('idna') 之类的操作时,我收到xn--http://-8fga3bl9al3aq0crdjw9y.xn--p1aiNotSupported: Unsupported URL scheme 'xn--http': no handler available for that scheme
    • @Helvdan 换一种方式试试:'http://сайтдляпримера.рф'.encode('idna').decode('utf-8')。这会将字节转换为 unicode 字符串
    • 这是同样的错误xceptions.TypeError: must be unicode, not str 因为'somestr'.method1().method2() 是一个链式调用。所以和你原来的答案没有区别。
    • @Helvdan 好的,看来问题是由您的网址的拉丁前缀编码引起的。试试这个:'http://' + 'сайтдляпримера.рф'.encode('idna').decode('utf-8')。我自己用urlopen 试了一下,效果很好。希望它也适用于scrapy
    • 你是救星。这已经奏效了。你能修改你的答案以匹配你最后的评论吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    • 2016-04-20
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    相关资源
    最近更新 更多