【问题标题】:Scrapy CrawlSpider retry scrapeScrapy CrawlSpider 重试抓取
【发布时间】:2015-09-19 03:57:53
【问题描述】:

对于我试图抓取的页面,我有时会在我的响应中返回一个“占位符”页面,其中包含一些自动重新加载的 javascript,直到它获得真正的页面。我可以检测到这种情况何时发生,我想重试下载和抓取页面。我在 CrawlSpider 中使用的逻辑类似于:

def parse_page(self, response):
    url = response.url

    # Check to make sure the page is loaded
    if 'var PageIsLoaded = false;' in response.body:
        self.logger.warning('parse_page encountered an incomplete rendering of {}'.format(url))
        yield Request(url, self.parse, dont_filter=True)
        return

    ...
    # Normal parsing logic

但是,似乎当调用重试逻辑并发出新请求时,它们包含的页面和链接不会被抓取或抓取。我的想法是,通过使用 CrawlSpider 用于应用爬网规则的self.parsedont_filter=True,我可以避免重复过滤器。但是使用DUPEFILTER_DEBUG = True,我可以看到重试请求被过滤掉了。

我错过了什么,还是有更好的方法来处理这个?如果可能的话,我想避免使用诸如 splash 之类的东西进行动态 js 渲染的复杂性,而这只会间歇性地发生。

【问题讨论】:

    标签: python scrapy scrapy-spider


    【解决方案1】:

    我会考虑改用custom Retry Middleware - 类似于built-in one

    示例实现(未测试):

    import logging
    
    logger = logging.getLogger(__name__)
    
    
    class RetryMiddleware(object):
        def process_response(self, request, response, spider):
            if 'var PageIsLoaded = false;' in response.body:
                logger.warning('parse_page encountered an incomplete rendering of {}'.format(response.url))
                return self._retry(request) or response
    
            return response
    
        def _retry(self, request):
            logger.debug("Retrying %(request)s", {'request': request})
    
            retryreq = request.copy()
            retryreq.dont_filter = True
            return retryreq
    

    别忘了activate它。

    【讨论】:

    • 中间件运行良好。我几乎可以重用内置的重试中间件,只需去掉异常代码的东西,然后用我自己的测试替换它。再次感谢您的帮助。
    • @JoshAdel 是的,scrapy 真的让一切都变得非常模块化和干净——所有的管道、中间件、扩展、项目加载器、输入和输出处理器——在非平凡且经常混乱的 web 中的优秀 API 接口-刮领域。很高兴为您提供帮助并感谢您提出一个有趣的问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 2014-12-31
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    相关资源
    最近更新 更多