我是python和scrapy的新手,现在我正在制作一个简单的scrapy项目,用于从论坛中抓取帖子。但是,有时在抓取帖子时,它获得了200但重定向到空页面(可能是因为论坛的不稳定服务器或其他原因,但无论如何)。我想对所有那些失败的人进行重试。
由于阅读全部内容太长,我想总结一下我的问题的方向:
1)我是否可以仅使用 CustomRetryMiddleware在一种特定方法中执行重试
2)我可以在完成第一次抓取后做某事
好的,让我们开始
我的代码的整体逻辑如下:
抓取论坛的主页
从主页抓取每个帖子
从帖子中删除数据
def start_requests(self):
yield scrapy.Request('https://www.forumurl.com', self.parse_page)
def parse_page(self, response): //Going into all the threads
hrefs = response.xpath('blahblah')
for href in hrefs:
url = response.urljoin(href.extract())
yield scrapy.Request(url, callback=self.parse_post)
def parse_post(self, response): //really scraping the content
content_empty = len(response.xpath('//table[@class="content"]') //check if the content is empty
if content_empty == 0:
//do something
item = ForumItem()
item['some_content'] = response.xpath('//someXpathCode')
yield item
我已经从stackoverflow中读过很多内容,并且认为我可以通过两种方式完成它(并且做了一些编码):
1)创建自定义RetryMiddleware
2)在蜘蛛内部重试
然而,我正在做他们两个没有运气。失败的原因如下:
对于Custom RetryMiddleware,我跟着this,但它将检查我抓取的所有页面,包括robot.txt,因此它总是重试。但我想要的只是在parse_post
内进行重试检查。这可能吗?
为了在蜘蛛内部重试,我尝试了两次接近。
首先,我添加了一个类变量_posts_not_crawled = []
,如果空检查为真,则将其附加response.url
。调整start_requests的代码,以便在第一次完成抓取后重试所有失败的抓取:
def start_requests(self):
yield scrapy.Request('https://www.forumurl.com', self.parse_page)
while self._post_not_crawled:
yield scrapy.Request(self._post_not_crawled.pop(0), callback=self.parse_post)
但当然它不起作用,因为它在实际抓取数据之前执行,所以它只会在开始抓取之前用空_post_not_crawled
列表执行一次。 完成第一次抓取后是否可以做某事?
第二次试用是直接在parse_post()
if content_empty == 0:
logging.warning('Post was empty: ' + response.url)
retryrequest = scrapy.Request(response.url, callback=self.parse_post)
retryrequest.dont_filter = True
return retryrequest
else:
//do the scraping
从此方法更新一些日志
2017-09-03 05:15:43 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://forum.hkgolden.com/view.aspx?type=BW&message=6778647> (referer: https://forum.hkgolden.com/topics.aspx?type=BW&page=2)
2017-09-03 05:15:43 [root] WARNING: Post was empty: https://forum.hkgolden.com/view.aspx?type=BW&message=6778647
2017-09-03 05:15:44 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://forum.hkgolden.com/view.aspx?type=BW&message=6778568> (referer: https://forum.hkgolden.com/topics.aspx?type=BW&page=2)
2017-09-03 05:15:44 [root] WARNING: Post was empty: https://forum.hkgolden.com/view.aspx?type=BW&message=6778568
2017-09-03 05:15:46 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://forum.hkgolden.com/view.aspx?type=BW&message=6774780> (referer: https://forum.hkgolden.com/topics.aspx?type=BW&page=2)
2017-09-03 05:15:46 [root] WARNING: Post was empty: https://forum.hkgolden.com/view.aspx?type=BW&message=6774780
但它也不起作用,retryrequest
只是跳过而没有任何迹象。
感谢您阅读所有这些内容。我感谢您的所有帮助。