【发布时间】:2018-07-04 14:40:21
【问题描述】:
我正在使用 scrapy 抓取 adidas 网站:http://www.adidas.com/us/men-shoes。
但它总是显示错误:
用户超时导致连接失败:获取http://www.adidas.com/us/men-shoes 耗时超过 180.0 秒..
它重试了 5 次,然后完全失败。
我可以访问 chrome 上的 url,但它不适用于 scrapy。
我尝试过使用自定义用户代理并模拟标头请求,但仍然无法正常工作。
下面是我的代码:
import scrapy
class AdidasSpider(scrapy.Spider):
name = "adidas"
def start_requests(self):
urls = ['http://www.adidas.com/us/men-shoes']
headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-US,en;q=0.9",
"Cache-Control": "max-age=0",
"Connection": "keep-alive",
"Host": "www.adidas.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
}
for url in urls:
yield scrapy.Request(url, self.parse, headers=headers)
def parse(self, response):
yield(response.body)
抓取日志:
{'downloader/exception_count': 1,
'downloader/exception_type_count/twisted.web._newclient.ResponseNeverReceived': 1,
'downloader/request_bytes': 224,
'downloader/request_count': 1,
'downloader/request_method_count/GET': 1,
'finish_reason': 'shutdown',
'finish_time': datetime.datetime(2018, 1, 25, 10, 59, 35, 57000),
'log_count/DEBUG': 2,
'log_count/INFO': 9,
'retry/count': 1,
'retry/reason_count/twisted.web._newclient.ResponseNeverReceived': 1,
'scheduler/dequeued': 1,
'scheduler/dequeued/memory': 1,
'scheduler/enqueued': 2,
'scheduler/enqueued/memory': 2,
'start_time': datetime.datetime(2018, 1, 25, 10, 58, 39, 550000)}
更新
在使用 fiddler 查看请求标头并进行一些测试后,我发现了导致问题的原因。 Scrapy 默认发送Connection: close 标头,因此我没有收到来自阿迪达斯网站的任何响应。
通过发出相同的请求但没有Connection: close 标头对提琴手进行测试后,我得到了正确的响应。现在的问题是如何删除Connection: close 标头?
【问题讨论】:
-
是时候离开tcpdump或wireshark了
-
我通过使用scrapy-splash解决了这个问题,
Connection标头可以在splash中被覆盖。 Scrapy 应该添加这个功能。 -
也许......但这看起来像是阿迪达斯网络服务器中的错误,而不是scrapy中的错误。
-
可能是,但我发现很少有其他人也有同样的问题。你试过了吗?你能更改/删除
Connection: close标头吗? -
这似乎与错误是在客户端还是在服务器中无关。阅读 HTTP RFC。由于
Connection: close的存在,您能找到服务器随机断开连接而不发送响应的理由吗?