Загрузчик Middleware игнорирует все запросы к определенному URL в scrapy


Я пытаюсь определить пользовательский загрузчик middleware в 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

И я добавляю это к диктату middleware:

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'

Эта ошибка возникает на самой первой странице, и я не могу понять, почему это происходит - я думаю, что я следил то, что сказано в инструкции. Что я делаю не так?

2 2

2 ответа:

Я нашел решение своей собственной проблемы-это была глупая ошибка с созданием класса и метода в 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.

Если вы знаете, какие запросы перенаправляются на проблемные, как насчет чего-то вроде:

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:
        ...

Таким образом, вы избегаете загрузки бесполезных ответов.

И вы всегда можете определить свое собственное промежуточное ПО для перенаправления.