Scrapy CrawlSpider重试刮擦


问题内容

对于我要抓取的页面,有时会在响应中返回“占位符”页面,其中包含一些自动重新加载直到获取真实页面的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

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

我是否缺少某些东西,或者有更好的方法来解决这个问题?我想避免使用splash之类的方法进行动态js渲染的复杂性,并且这种情况只会间歇性地发生。


问题答案:

我会考虑使用 自定义的Retry
Middleware

,它类似于内置的

实施示例(未经测试):

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

并且不要忘记激活它。