Scrapy CrawlSpider重试刮擦

Jos*_*del 2 python scrapy scrapy-spider

对于我试图抓取的页面,我有时会在我的响应中找到一个"占位符"页面,其中包含一些自动加载的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
Run Code Online (Sandbox Code Playgroud)

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

我错过了什么,还是有更好的方法来解决这个问题?如果可能的话,我想避免使用像splash这样的动态js渲染的复杂性,这只是间歇性地发生.

ale*_*cxe 5

我会考虑使用自定义重试中间件 - 类似于内置的.

示例实现(未测试):

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
Run Code Online (Sandbox Code Playgroud)

别忘了激活它.