MIT*_*THU 3 python scrapy web-scraping python-3.x
我使用scrapy创建了一个脚本,即使这些链接无效并得到404响应,它也能够递归地重试列表中的一些链接。我使用dont_filter=Trueand '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()
Run Code Online (Sandbox Code Playgroud)
如何让脚本最多重试五次?
注意:列表中有多个相同的 url。我不想踢出重复的链接。我想让scrapy 使用所有的url。
我可以提出以下说明:
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
}
....
Run Code Online (Sandbox Code Playgroud)
dont_filter=True-scrapy 应用程序将访问以前访问过的页面。从您的代码中dont_filter=True应该可以解决无限循环问题但它只是无限重试。