python - 除非中间有 200 个状态,否则无法强制脚本重试五次
问题描述
我使用scrapy创建了一个脚本,它能够递归地重试列表中的一些链接,即使这些链接无效并得到404
响应。我使用dont_filter=True
and 'handle_httpstatus_list': [404]
insidemeta
来实现当前的行为。我现在要做的是让脚本做同样的事情 5 次,除非200 status
中间有。我已经考虑"max_retry_times":5
了meta
这样一个事实,即它最多会重试五次,但它只是无限重试。
到目前为止我已经尝试过:
import scrapy
from bs4 import BeautifulSoup
from scrapy.crawler import CrawlerProcess
class StackoverflowSpider(scrapy.Spider):
name = "stackoverflow"
start_urls = [
"https://stackoverflow.com/questions/taggedweb-scraping",
"https://stackoverflow.com/questions/taggedweb-scraping"
]
def start_requests(self):
for start_url in self.start_urls:
yield scrapy.Request(start_url,callback=self.parse,meta={"start_url":start_url,'handle_httpstatus_list': [404],"max_retry_times":5},dont_filter=True)
def parse(self,response):
if response.meta.get("start_url"):
start_url = response.meta.get("start_url")
soup = BeautifulSoup(response.text,'lxml')
if soup.select(".summary .question-hyperlink"):
for item in soup.select(".summary .question-hyperlink"):
title_link = response.urljoin(item.get("href"))
print(title_link)
else:
print("++++++++++"*20) # to be sure about the recursion
yield scrapy.Request(start_url,meta={"start_url":start_url,'handle_httpstatus_list': [404],"max_retry_times":5},dont_filter=True,callback=self.parse)
if __name__ == "__main__":
c = CrawlerProcess({
'USER_AGENT':'Mozilla/5.0',
})
c.crawl(StackoverflowSpider)
c.start()
如何让脚本最多重试五次?
注意:列表中有多个相同的 url。我不想踢出重复的链接。我想让scrapy使用所有的网址。
解决方案
我可以建议以下方向:
1. 将404
代码添加到RETRY_HTTP_CODES
设置中,因为它默认不包含响应代码404
。
即使链接无效并获得 404 响应,也能够递归重试链接
class StackoverflowSpider(scrapy.Spider):
name = "stackoverflow"
custom_settings = {
'RETRY_HTTP_CODES' : [500, 502, 503, 504, 522, 524, 408, 429 , 404],
'RETRY_TIMES': 5 # usage of "max_retry_times" meta key is also valid
}
....
- with
dont_filter=True
- scrapy 应用程序将访问以前访问过的页面。
从您的代码中删除dont_filter=True
应该可以解决无限循环问题
但它只是无限重试。