3

我正在尝试在 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'

这个错误发生在抓取的第一页上,我无法弄清楚它为什么会发生 - 我想我已经按照手册所说的去做了。我究竟做错了什么?

4

2 回答 2

10

我找到了解决我自己问题的方法——在 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.

于 2012-12-29T00:01:15.087 回答
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:
        ...

这样您就可以避免下载无用的响应。

而且您始终可以定义自己的自定义重定向中间件。

于 2017-10-23T10:00:50.563 回答