我正在尝试在Scrapy中定义一个自定义下载器中间件,以忽略对特定URL的所有请求(这些请求是从其他URL重定向的,所以当我首先生成请求时,我无法将其过滤掉)。
我有以下代码,其中的想法是在响应处理阶段捕获这个(因为我不完全确定重定向到其他请求的请求是如何工作的),检查URL,如果它与我匹配的那个我试图过滤掉然后返回一个IgnoreRequest异常,如果没有,像往常一样返回响应,以便继续处理它。
from scrapy.exceptions import IgnoreRequest
from scrapy import log
class CustomDownloaderMiddleware:
def process_response(request, response, spider):
log.msg("In Middleware " + response.url, level=log.WARNING)
if response.url == "http://www.achurchnearyou.com//":
return IgnoreRequest()
else:
return response
我将其添加到中间件的字典中:
DOWNLOADER_MIDDLEWARES = {
'acny.middlewares.CustomDownloaderMiddleware': 650
}
值为650,我认为应该在RedirectMiddleware之后直接运行。
但是,当我运行抓取工具时,我收到错误消息:
ERROR: Error downloading <GET http://www.achurchnearyou.com/venue.php?V=00001>: process_response() got multiple values for keyword argument 'request'
这个错误发生在抓取的第一个页面上,我无法弄清楚它为什么会发生 - 我想我已经按照手册所说的去做了。我做错了什么?
答案 0 :(得分:7)
我找到了解决自己问题的方法 - 在Python中创建类和方法是一个愚蠢的错误。上面的代码必须是:
from scrapy.exceptions import IgnoreRequest
from scrapy import log
class CustomDownloaderMiddleware(object):
def process_response(self, request, response, spider):
log.msg("In Middleware " + response.url, level=log.WARNING)
if response.url == "http://www.achurchnearyou.com//":
raise IgnoreRequest()
else:
return response
也就是说,该方法需要self
参数作为第一个参数,并且该类需要从object
继承。
答案 1 :(得分:0)
如果您知道哪些请求被重定向到有问题的请求,那么如何:
def parse_requests(self, response):
....
meta = {'handle_httpstatus_list': [301, 302]}
callback = 'process_redirects'
yield Request(url, callback=callback, meta=meta, ...)
def process_redirects(self, response):
url = response.headers['location']
if url is no good:
return
else:
...
这样可以避免下载无用的响应。
您可以随时定义自己的自定义重定向中间件。