Scrapy在收益后进行重试

时间:2017-09-01 10:20:04

标签: python web-scraping scrapy scrapy-middleware

我是python和scrapy的新手,现在我正在制作一个简单的scrapy项目,用于从论坛中抓取帖子。但是,有时在抓取帖子时,它获得了200但重定向到空页面(可能是因为论坛的不稳定服务器或其他原因,但无论如何)。我想对所有那些失败的人进行重试。

由于阅读全部内容太长,我想总结一下我的问题的方向:

1)我是否可以仅使用 CustomRetryMiddleware在一种特定方法中执行重试

2)我可以在完成第一次抓取后做某事

好的,让我们开始

我的代码的整体逻辑如下:

  1. 抓取论坛的主页

  2. 从主页抓取每个帖子

  3. 从帖子中删除数据

      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
    
  4. 我已经从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只是跳过而没有任何迹象。

    感谢您阅读所有这些内容。我感谢您的所有帮助。

0 个答案:

没有答案