Загрузчик 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 ответа:
Я нашел решение своей собственной проблемы-это была глупая ошибка с созданием класса и метода в 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: ...
Таким образом, вы избегаете загрузки бесполезных ответов.
И вы всегда можете определить свое собственное промежуточное ПО для перенаправления.