Scrapy:将信息发送到先前的功能

use*_*629 7 python scrapy

我正在使用scrapy 1.1来抓一个网站.该网站需要定期重新登录.我知道何时需要这个,因为当需要登录时,会发生302重定向.基于#http://sangaline.com/post/advanced-web-scraping-tutorial/,我已经将RedirectMiddleware子类化,使蜘蛛中的位置http头可用于:

request.meta['redirect_urls']
Run Code Online (Sandbox Code Playgroud)

我的问题是登录后,我已经设置了一个函数来循环100页来刮.让我们说15页后,我发现我必须重新登录(根据request.meta ['redirect_urls']的内容).我的代码看起来像:

def test1(self, response):

    ......
    for row in empties: # 100 records
        d = object_as_dict(row)

        AA

        yield Request(url=myurl,headers=self.headers, callback=self.parse_lookup, meta={d':d}, dont_filter=True)

def parse_lookup(self, response):

    if 'redirect_urls' in response.meta:
        print str(response.meta['redirect_urls'])

        BB

    d = response.meta['d']
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我收到了'通知'需要在BB中的parse_lookup重新登录,但需要反馈这些信息以取消在test1(AA)中创建请求的循环.如何在先前的回调函数中使用解析查找中的信息?

Hen*_*ura 5

为什么不使用DownloaderMiddleware?

您可以像这样编写DownloaderMiddleware:

编辑:我编辑了原始代码,以解决OP在评论中遇到的第二个问题.

from scrapy.http import Request

class CustomMiddleware():

    def process_response(self, request, response, spider):
        if 'redirect_urls' in response.meta:
            # assuming your spider has a method for handling the login
            original_url = response.meta["redirect_urls"][0]
            return Request(url="login_url", 
                           callback=spider.login, 
                           meta={"original_url": original_url})
        return response
Run Code Online (Sandbox Code Playgroud)

因此,在进入parse_lookup并重新登录/修复错误并产生新请求之前,您将"拦截"响应...

就像TomášLinhart所说的那样,请求是异步的,所以我不知道你是否可以通过连续几次"重新登录"来遇到问题,因为多个请求可能同时被重定向.

请记住将中间件添加到您的设置:

DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.redirect.RedirectMiddleware': 542,
    'myproject.middlewares.CustomDownloaderMiddleware': 543,
}
Run Code Online (Sandbox Code Playgroud)