无法使用Scrapy修改中间件中的请求

时间:2018-12-26 23:01:01

标签: web-scraping scrapy scrapy-spider

我正在抓取有关项目的理论(数据科学)的公共数据,为了有效地做到这一点,我需要在403响应代码的情况下更改在我的scrapy请求上使用的代理。< / p>

为此,我定义了一个下载中间件来处理这种情况,如下所示

class ProxyMiddleware(object):    
    def process_response(self, request, response, spider):
        if response.status == 403:
            f = open("Proxies.txt")
            proxy = random_line(f) # Just returns a random line from the file with a valid structure ("http://IP:port")
            new_request = Request(url=request.url)
            new_request.meta['proxy'] = proxy
            spider.logger.info("[Response 403] Changed proxy to %s" % proxy)
            return new_request
        return response

在将类正确添加到settings.py之后,我希望该中间件通过使用新代理生成新请求来处理403响应,从而最终获得200响应。观察到的行为是它实际上已被执行(我可以看到有关已更改代理的Logger信息),但是似乎没有发出新请求。相反,我得到了这个:

2018-12-26 23:33:19 [bot_2] INFO: [Response] Changed proxy to https://154.65.93.126:53281
2018-12-26 23:33:26 [bot_2] INFO: [Response] Changed proxy to https://176.196.84.138:51336

...无限期地使用随机代理,这使我认为我仍在检索403错误,并且代理服务器未更改。

阅读the documentation,有关 process_response ,其中指出:

  

(...)如果返回一个Request对象,则中间件链将暂停,并且返回的请求将重新安排为在将来下载。这与从process_request()返回请求的行为相同。

“将来”是否可能不是“返回后立即”?从那一刻起,我该如何更改所有请求的代理?

2 个答案:

答案 0 :(得分:1)

默认情况下,Scrapy会将重复的请求丢弃到相同的url,所以这可能就是您的蜘蛛正在发生的事情。要检查您是否遇到这种情况,可以设置以下设置:

DUPEFILTER_DEBUG=True
LOG_LEVEL='DEBUG'

要解决此问题,您应该添加dont_filter=True

new_request = Request(url=request.url, dont_filter=True)

答案 1 :(得分:0)

尝试一下:

class ProxyMiddleware(object):    
    def process_response(self, request, response, spider):
        if response.status == 403:
            f = open("Proxies.txt")
            proxy = random_line(f)
            new_request = Request(url=request.url)
            new_request.meta['proxy'] = proxy
            spider.logger.info("[Response 403] Changed proxy to %s" % proxy)
            return new_request
        else:
            return response

更好的方法是改为使用scrapy随机代理模块:

'DOWNLOADER_MIDDLEWARES' : {
    'rotating_proxies.middlewares.RotatingProxyMiddleware': 610,
    'rotating_proxies.middlewares.BanDetectionMiddleware': 620
},