如何在scrapy中处理302重定向

mrk*_*rki 12 python scrapy http-status-code-302

报废网站时,我收到服务器的302响应:

2014-04-01 21:31:51+0200 [ahrefs-h] DEBUG: Redirecting (302) to <GET http://www.domain.com/Site_Abuse/DeadEnd.htm> from <GET http://domain.com/wps/showmodel.asp?Type=15&make=damc&a=664&b=51&c=0>
Run Code Online (Sandbox Code Playgroud)

我想向GET网址发送请求,而不是重定向.现在我找到了这个中间件:

https://github.com/scrapy/scrapy/blob/master/scrapy/contrib/downloadermiddleware/redirect.py#L31

我将此重定向代码添加到我的middleware.py文件中,然后将其添加到settings.py中:

DOWNLOADER_MIDDLEWARES = {
 'street.middlewares.RandomUserAgentMiddleware': 400,
 'street.middlewares.RedirectMiddleware': 100,
 'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None,
}
Run Code Online (Sandbox Code Playgroud)

但我仍然被重定向.这是我为了让这个中间件工作所必须做的吗?我错过了什么吗?

mrk*_*rki 11

在这种情况下忘了中间件,这将解决问题:

meta = {'dont_redirect': True,'handle_httpstatus_list': [302]}
Run Code Online (Sandbox Code Playgroud)

也就是说,当您提出请求时,您需要包含元参数:

yield Request(item['link'],meta = {
                  'dont_redirect': True,
                  'handle_httpstatus_list': [302]
              }, callback=self.your_callback)
Run Code Online (Sandbox Code Playgroud)


Gal*_*cio 5

无法解释的302响应,例如从在 Web 浏览器中正常加载的页面重定向到主页或某个固定页面,通常表示服务器端针对不需要的活动采取的措施。

您必须降低抓取速度或使用智能代理(例如Crawlera)或代理轮换服务,并在收到此类响应时重试您的请求。

要重试这样的响应,请添加'handle_httpstatus_list': [302]meta源请求的 ,并检查是否response.status == 302在回调中。如果是,请通过 yield 重试您的请求response.request.replace(dont_filter=True)

重试时,您还应该让您的代码限制任何给定 URL 的最大重试次数。您可以保留一个字典来跟踪重试:

class MySpider(Spider):
    name = 'my_spider'

    max_retries = 2

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.retries = {}

    def start_requests(self):
        yield Request(
            'https://example.com',
            callback=self.parse,
            meta={
                'handle_httpstatus_list': [302],
            },
        )

    def parse(self, response):
        if response.status == 302:
            retries = self.retries.setdefault(response.url, 0)
            if retries < self.max_retries:
                self.retries[response.url] += 1
                yield response.request.replace(dont_filter=True)
            else:
                self.logger.error('%s still returns 302 responses after %s retries',
                                  response.url, retries)
            return
Run Code Online (Sandbox Code Playgroud)

根据场景,您可能希望将此代码移动到下载器中间件


war*_*iuc 1

我将此重定向代码添加到 middleware.py 文件中,并将其添加到 settings.py 中:

DOWNLOADER_MIDDLEWARES_BASERedirectMiddleware默认情况下已经启用,所以你做什么并不重要。

我想将请求发送到 GET url 而不是被重定向。

如何?服务器响应302您的GET请求。如果您GET再次访问同一 URL,您将再次被重定向。

你想达到什么目的?

如果您不想被重定向,请参阅以下问题: