Scrapy error:User timeout caused connection failure
Scrapy error:User timeout caused connection failure
我正在使用 scrapy 抓取阿迪达斯网站:http://www.adidas.com/us/men-shoes
。
但是总是报错:
User timeout caused connection failure: Getting http://www.adidas.com/us/men-shoes took longer than 180.0 seconds..
重试5次完全失败
我可以在 chrome 上访问 url 但它在 scrapy 上不起作用。
我试过使用自定义用户代理并模拟 header 请求,但它仍然不起作用。
下面是我的代码:
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)
Scrapy 日志:
{'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 查看请求 headers 并进行一些测试后,我发现了导致问题的原因。 Scrapy 默认发送 Connection: close
header,因此我没有从阿迪达斯网站收到任何回复。
通过发出相同的请求但没有 Connection: close
header 对 fiddler 进行测试后,我得到了正确的响应。现在的问题是如何删除 Connection: close
header?
我尝试使用 curl
访问网站,但连接挂起。
curl -v -L http://www.adidas.com/us/men-shoes
所以我跳进了浏览器的调试器,发现请求中有一个 Cookie
header。因此,我从 header 复制了整个值并将其粘贴到 curl --headers
命令中。
curl -v -L -H 'Cookie:<cookie value here>' http://www.adidas.com/us/men-shoes
现在 HTML 内容 returns。因此,网站有时会设置访问网站其余部分所需的 cookie。不幸的是,我不确定在何处或如何以编程方式获取 cookie。如果您弄清楚了,请告诉我们。希望这有帮助。
更新
看起来有一些方法可以在 Scrapy 中使用持久的 session 数据(即 cookies)(直到现在我才不得不使用它 :))。看看this answer and this doc。我想也许该网站正在重定向设置 cookie 的请求,但事实并非如此。所以修复起来应该是比较简单的问题。
好吧,至少你应该使用你写的 headers,将 'headers=headers' 添加到你的 scrapy.Request。但是,即使在我尝试 yield scrapy.Request(url, self.parse, headers=headers)
之后它仍然无法正常工作
所以接下来我将 settings.py 中的 User-Agent 更改为您的 headers 中的 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" 和没有使用你在 scrapy.Request 中写的 headers,它起作用了。
也许 headers 有问题。但我很确定这与 cookie 无关。
使用您的代码,第一个连接对我来说工作正常 - 它使用您提供的 headers 并获得正确的响应。我修改了您的 parse
方法以跟踪产品链接并从收到的页面打印 <title>
标签的内容,并且效果也很好。示例日志和打印输出如下。我怀疑您是因为请求过多而速度变慢了。
2018-01-27 16:48:23 [scrapy.core.engine] INFO: Spider opened
2018-01-27 16:48:23 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2018-01-27 16:48:23 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2018-01-27 16:48:24 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://www.adidas.com/us/men-shoes> (referer: None)
2018-01-27 16:48:25 [scrapy.dupefilters] DEBUG: Filtered duplicate request: <GET http://www.adidas.com/> - no more duplicates will be shown (see DUPEFILTER_DEBUG to show all duplicates)
2018-01-27 16:48:25 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://www.adidas.com/us/alphabounce-beyond-shoes/DB1126.html> from <GET http://www.adidas.com/us/alphabounce-beyond-shoes/DB1126.html>
2018-01-27 16:48:25 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://www.adidas.com/us/ultraboost-laceless-shoes/BB6137.html> from <GET http://www.adidas.com/us/ultraboost-laceless-shoes/BB6137.html>
<snipped a bunch>
2018-01-27 16:48:26 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.adidas.com/us/> (referer: http://www.adidas.com/us/men-shoes)
2018-01-27 16:48:26 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.adidas.com/us/nmd_cs2-primeknit-shoes/BY3012.html> (referer: http://www.adidas.com/us/men-shoes)
adidas Alphabounce Beyond Shoes - White | adidas US
adidas UA&SONS NMD R2 Shoes - Grey | adidas US
adidas NMD_C2 Shoes - Brown | adidas US
adidas NMD_CS2 Primeknit Shoes - Grey | adidas US
adidas NMD_Racer Primeknit Shoes - Black | adidas US
adidas Official Website | adidas US
adidas NMD_CS2 Primeknit Shoes - Black | adidas US
2018-01-27 16:48:26 [scrapy.core.engine] INFO: Closing spider (finished)
2018-01-27 16:48:26 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
您可以使用此工具 https://curl.trillworks.com/ 来
- 从 Chrome
获取 curl 命令
- 运行 转换后的 python 代码(我通过请求从您的 URL 得到了响应 200)
- 为您的 scrapy.Request
复制 headers 和 cookie
因为 scrapy 不允许您编辑 Connection: close
header。我使用 scrapy-splash 而不是使用 splash 发出请求。
现在 Connection: close
header 可以被覆盖,现在一切正常。缺点是现在网页必须在我从启动响应中加载所有资产,速度较慢但有效。
Scrapy 应该添加选项来编辑它们的默认 Connection: close
header。它是硬编码在库中的,不能轻易覆盖。
下面是我的工作代码:
headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Host": "www.adidas.com",
"Connection": "keep-alive",
"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"
}
def start_requests(self):
url = "http://www.adidas.com/us/men-shoes?sz=120&start=0"
yield SplashRequest(url, self.parse, headers=self.headers)
我正在使用 scrapy 抓取阿迪达斯网站:http://www.adidas.com/us/men-shoes
。
但是总是报错:
User timeout caused connection failure: Getting http://www.adidas.com/us/men-shoes took longer than 180.0 seconds..
重试5次完全失败
我可以在 chrome 上访问 url 但它在 scrapy 上不起作用。
我试过使用自定义用户代理并模拟 header 请求,但它仍然不起作用。
下面是我的代码:
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)
Scrapy 日志:
{'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 查看请求 headers 并进行一些测试后,我发现了导致问题的原因。 Scrapy 默认发送 Connection: close
header,因此我没有从阿迪达斯网站收到任何回复。
通过发出相同的请求但没有 Connection: close
header 对 fiddler 进行测试后,我得到了正确的响应。现在的问题是如何删除 Connection: close
header?
我尝试使用 curl
访问网站,但连接挂起。
curl -v -L http://www.adidas.com/us/men-shoes
所以我跳进了浏览器的调试器,发现请求中有一个 Cookie
header。因此,我从 header 复制了整个值并将其粘贴到 curl --headers
命令中。
curl -v -L -H 'Cookie:<cookie value here>' http://www.adidas.com/us/men-shoes
现在 HTML 内容 returns。因此,网站有时会设置访问网站其余部分所需的 cookie。不幸的是,我不确定在何处或如何以编程方式获取 cookie。如果您弄清楚了,请告诉我们。希望这有帮助。
更新
看起来有一些方法可以在 Scrapy 中使用持久的 session 数据(即 cookies)(直到现在我才不得不使用它 :))。看看this answer and this doc。我想也许该网站正在重定向设置 cookie 的请求,但事实并非如此。所以修复起来应该是比较简单的问题。
好吧,至少你应该使用你写的 headers,将 'headers=headers' 添加到你的 scrapy.Request。但是,即使在我尝试 yield scrapy.Request(url, self.parse, headers=headers)
之后它仍然无法正常工作所以接下来我将 settings.py 中的 User-Agent 更改为您的 headers 中的 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" 和没有使用你在 scrapy.Request 中写的 headers,它起作用了。
也许 headers 有问题。但我很确定这与 cookie 无关。
使用您的代码,第一个连接对我来说工作正常 - 它使用您提供的 headers 并获得正确的响应。我修改了您的 parse
方法以跟踪产品链接并从收到的页面打印 <title>
标签的内容,并且效果也很好。示例日志和打印输出如下。我怀疑您是因为请求过多而速度变慢了。
2018-01-27 16:48:23 [scrapy.core.engine] INFO: Spider opened
2018-01-27 16:48:23 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2018-01-27 16:48:23 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2018-01-27 16:48:24 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://www.adidas.com/us/men-shoes> (referer: None)
2018-01-27 16:48:25 [scrapy.dupefilters] DEBUG: Filtered duplicate request: <GET http://www.adidas.com/> - no more duplicates will be shown (see DUPEFILTER_DEBUG to show all duplicates)
2018-01-27 16:48:25 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://www.adidas.com/us/alphabounce-beyond-shoes/DB1126.html> from <GET http://www.adidas.com/us/alphabounce-beyond-shoes/DB1126.html>
2018-01-27 16:48:25 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://www.adidas.com/us/ultraboost-laceless-shoes/BB6137.html> from <GET http://www.adidas.com/us/ultraboost-laceless-shoes/BB6137.html>
<snipped a bunch>
2018-01-27 16:48:26 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.adidas.com/us/> (referer: http://www.adidas.com/us/men-shoes)
2018-01-27 16:48:26 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.adidas.com/us/nmd_cs2-primeknit-shoes/BY3012.html> (referer: http://www.adidas.com/us/men-shoes)
adidas Alphabounce Beyond Shoes - White | adidas US
adidas UA&SONS NMD R2 Shoes - Grey | adidas US
adidas NMD_C2 Shoes - Brown | adidas US
adidas NMD_CS2 Primeknit Shoes - Grey | adidas US
adidas NMD_Racer Primeknit Shoes - Black | adidas US
adidas Official Website | adidas US
adidas NMD_CS2 Primeknit Shoes - Black | adidas US
2018-01-27 16:48:26 [scrapy.core.engine] INFO: Closing spider (finished)
2018-01-27 16:48:26 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
您可以使用此工具 https://curl.trillworks.com/ 来
- 从 Chrome 获取 curl 命令
- 运行 转换后的 python 代码(我通过请求从您的 URL 得到了响应 200)
- 为您的 scrapy.Request 复制 headers 和 cookie
因为 scrapy 不允许您编辑 Connection: close
header。我使用 scrapy-splash 而不是使用 splash 发出请求。
现在 Connection: close
header 可以被覆盖,现在一切正常。缺点是现在网页必须在我从启动响应中加载所有资产,速度较慢但有效。
Scrapy 应该添加选项来编辑它们的默认 Connection: close
header。它是硬编码在库中的,不能轻易覆盖。
下面是我的工作代码:
headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Host": "www.adidas.com",
"Connection": "keep-alive",
"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"
}
def start_requests(self):
url = "http://www.adidas.com/us/men-shoes?sz=120&start=0"
yield SplashRequest(url, self.parse, headers=self.headers)