回调重定向请求Scrapy

时间:2016-03-05 05:04:01

标签: redirect scrapy web-crawler url-redirection scrapy-spider

我正在尝试使用刮擦框架。某些请求被重定向,但是没有为这些重定向的url请求调用start_requests中设置的回调函数,但对于非重定向的请求可以正常工作。

我在start_requests函数中有以下代码:

for user in users:
    yield scrapy.Request(url=userBaseUrl+str(user['userId']),cookies=cookies,headers=headers,dont_filter=True,callback=self.parse_p)

但是,仅针对非302请求调用此self.parse_p。

2 个答案:

答案 0 :(得分:4)

我猜你会得到最后一页的回调(重定向之后)。重定向由RedirectMiddleware处理。您可以禁用它,然后您必须手动执行所有重定向。如果您想有选择地禁用几种类型的请求的重定向,您可以这样做:

request =  scrapy.Request(url, meta={'dont_redirect': True} callback=self.manual_handle_of_redirects)

我不确定中间请求/响应是否非常有趣。这也是RedirectMiddleware所相信的。因此,它会自动执行重定向并将中间URL(唯一有趣的内容)保存在:

response.request.meta.get('redirect_urls')

你有几个选择!

示例蜘蛛:

import scrapy

class DimSpider(scrapy.Spider):
    name = "dim"

    start_urls = (
        'http://example.com/',
    )

    def parse(self, response):
        yield scrapy.Request(url="http://example.com/redirect302.php", dont_filter=True, callback=self.parse_p)

    def parse_p(self, response):
       print response.request.meta.get('redirect_urls')
       print "done!"

示例输出......

DEBUG: Crawled (200) <GET http://www.example.com/> (referer: None)
DEBUG: Redirecting (302) to <GET http://myredirect.com> from <GET http://example.com/redirect302.php>
DEBUG: Crawled (200) <GET http://myredirect.com/> (referer: http://example.com/redirect302.com/)
['http://example.com/redirect302.php']
done!

如果你真的想刮掉302页,你必须明确地允许它。例如,我允许302并将dont_redirect设置为True

handle_httpstatus_list = [302]
def parse(self, response):
    r = scrapy.Request(url="http://example.com/redirect302.php", dont_filter=True, callback=self.parse_p)
    r.meta['dont_redirect'] = True
    yield r

最终结果是:

DEBUG: Crawled (200) <GET http://www.example.com/> (referer: None)
DEBUG: Crawled (302) <GET http://example.com/redirect302.com/> (referer: http://www.example.com/)
None
done!

这个蜘蛛应该手动关注302网址:

import scrapy

class DimSpider(scrapy.Spider):
    name = "dim"

    handle_httpstatus_list = [302]

    def start_requests(self):
        yield scrapy.Request("http://page_with_or_without_redirect.html",
                             callback=self.parse200_or_302, meta={'dont_redirect':True})

    def parse200_or_302(self, response):
        print "I'm on: %s with status %d" % (response.url, response.status)
        if 'location' in response.headers:
            print "redirecting"
            return [scrapy.Request(response.headers['Location'],
                                  callback=self.parse200_or_302, meta={'dont_redirect':True})]

小心点。不要忽略设置handle_httpstatus_list = [302],否则您将收到“未处理或不允许HTTP状态代码”。

答案 1 :(得分:0)

默认情况下,scrapy不会遵循302重定向。

在您的蜘蛛中,您可以使用custom_settings属性:

  

custom_settings   运行此蜘蛛时将从项目范围配置中覆盖的设置字典。必须将其定义为类属性,因为在实例化之前更新了设置。

设置可以重定向网址请求的重定向数量,如下所示:

class MySpider(scrapy.Spider):
  name = "myspider"
  allowed_domains = ["example.com"]
  start_urls = [ "http://www.example.com" ]

  custom_settings = { 'REDIRECT_MAX_TIMES': 333 }

  def start_requests(self):
      # Your code here

我将333设置为示例限制。

我希望这会有所帮助。