Scrapy重试或重定向中间件

时间:2013-12-27 18:33:48

标签: python redirect python-2.7 scrapy

在使用scrapy浏览网站时,我会在约1/5的时间内被重定向到用户阻止的网页。当发生这种情况时,我丢失了从重定向的页面。我不知道在中间件中使用哪个中间件或使用什么设置,但我想要这个:

DEBUG: Redirecting (302) to (GET http://domain.com/foo.aspx) from (GET http://domain.com/bar.htm)

不要掉落bar.htm。当刮刀完成时,我最终没有来自bar.htm的数据,但我正在旋转代理,所以如果它再次尝试bar.htm(可能再多次),我应该得到它。如何设置尝试次数?

如果重要的话,我只允许抓取工具使用一个非常具体的起始网址然后只按照“下一页”链接,所以它应该按顺序通过少量页面 - 因此我需要它重试,例如,第34页,或稍后再回来。 Scrapy文档说默认情况下应该重试20次,但我根本没有看到它重试。此外,如果它有帮助:所有重定向都转到同一页面(一个“离开”页面,上面的foo.com) - 有没有办法告诉Scrapy该特定页面“不计数”,如果它被重定向到那里,继续重试?我在下载程序中间件中看到了一些引用列表中特定http代码的内容 - 我可以以某种方式向“始终不断尝试此”列表中添加302吗?

2 个答案:

答案 0 :(得分:5)

我今天遇到的问题与使用301..303重定向的网站有关,但有时也会进行元重定向。我构建了retry middleware并使用了redirect中间件中的一些块:

from scrapy.contrib.downloadermiddleware.retry import RetryMiddleware
from scrapy.selector import HtmlXPathSelector
from scrapy.utils.response import get_meta_refresh
from scrapy import log

class CustomRetryMiddleware(RetryMiddleware):

    def process_response(self, request, response, spider):
        url = response.url
        if response.status in [301, 307]:
            log.msg("trying to redirect us: %s" %url, level=log.INFO)
            reason = 'redirect %d' %response.status
            return self._retry(request, reason, spider) or response
        interval, redirect_url = get_meta_refresh(response)
        # handle meta redirect
        if redirect_url:
            log.msg("trying to redirect us: %s" %url, level=log.INFO)
            reason = 'meta'
            return self._retry(request, reason, spider) or response
        hxs = HtmlXPathSelector(response)
        # test for captcha page
        captcha = hxs.select(".//input[contains(@id, 'captchacharacters')]").extract()
        if captcha:
            log.msg("captcha page %s" %url, level=log.INFO)
            reason = 'capcha'
            return self._retry(request, reason, spider) or response
        return response

为了使用这个中间件,最好在settings.py中禁用此项目的退出重定向中间件:

DOWNLOADER_MIDDLEWARES = {
                         'YOUR_PROJECT.scraper.middlewares.CustomRetryMiddleware': 120,
                          'scrapy.contrib.downloadermiddleware.redirect.RedirectMiddleware': None,
                          'scrapy.contrib.downloadermiddleware.redirect.MetaRefreshMiddleware': None,
}

答案 1 :(得分:4)

您可以通过在蜘蛛开头添加handle_httpstatus_list = [302]来处理302个回复,如下所示:

class MySpider(CrawlSpider):
    handle_httpstatus_list = [302]

    def parse(self, response):
        if response.status == 302:
            # Store response.url somewhere and go back to it later