【发布时间】:2020-12-22 14:04:13
【问题描述】:
我使用scrapy 创建了一个脚本,它能够递归地重试列表中的某些链接,即使这些链接无效并得到404 响应。我在meta 中使用了dont_filter=True 和'handle_httpstatus_list': [404] 来实现当前行为。我现在要做的是让脚本做同样的事情 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使用所有的url。
【问题讨论】:
-
这里只是评论,你用scrapy的时候不需要bs4。你可以简单地
response.css(".summary .question-hyperlink::attr(href)").getall()。 Check Scrapy docs for more info on selectors -
感谢@Thiago Curvelo 的指点。我已经知道了。
标签: python python-3.x web-scraping scrapy