Захват HTTP-кодов состояния с помощью паука-скрапа
Я новичок в области терапии. Я пишу паука, предназначенного для проверки длинного списка URL-адресов для кодов состояния сервера и, при необходимости, на какие URL они перенаправлены. Важно отметить, что при наличии цепочки перенаправлений мне нужно знать код состояния и URL-адрес при каждом переходе. Я использую response.meta ["redirect_urls"] для захвата URL-адресов, но не уверен, как захватить коды состояния - похоже, мета-ключ ответа для него не существует.
Я понимаю, что мне может понадобиться написать какую-нибудь специальную промежуточную одежду, чтобы раскрыть эти значения, но не совсем понятно, как регистрировать коды состояния для каждого прыжка, или как получить доступ к этим значениям из паука. Я посмотрел, но не могу найти пример того, кто это делает. Если кто-нибудь может указать мне правильное направление, это будет очень цениться.
Например,
items = []
item = RedirectItem()
item['url'] = response.url
item['redirected_urls'] = response.meta['redirect_urls']
item['status_codes'] = #????
items.append(item)
Edit - На основе отзывов от warawauk и некоторой действительно активной помощи от ребят на канале IRC (freenode #scrappy) мне удалось это сделать. Я считаю, что это немного хакерски, поэтому любые комментарии по улучшению приветствуются:
(1) Отключите промежуточное ПО по умолчанию в настройках и добавьте свое собственное:
DOWNLOADER_MIDDLEWARES = {
'scrapy.contrib.downloadermiddleware.redirect.RedirectMiddleware': None,
'myproject.middlewares.CustomRedirectMiddleware': 100,
}
(2) Создайте свое CustomRedirectMiddleware в файле middlewares.py. Он наследуется от основного класса redirectmiddleware и перехватывает перенаправление:
class CustomRedirectMiddleware(RedirectMiddleware):
"""Handle redirection of requests based on response status and meta-refresh html tag"""
def process_response(self, request, response, spider):
#Get the redirect status codes
request.meta.setdefault('redirect_status', []).append(response.status)
if 'dont_redirect' in request.meta:
return response
if request.method.upper() == 'HEAD':
if response.status in [301, 302, 303, 307] and 'Location' in response.headers:
redirected_url = urljoin(request.url, response.headers['location'])
redirected = request.replace(url=redirected_url)
return self._redirect(redirected, request, spider, response.status)
else:
return response
if response.status in [302, 303] and 'Location' in response.headers:
redirected_url = urljoin(request.url, response.headers['location'])
redirected = self._redirect_request_using_get(request, redirected_url)
return self._redirect(redirected, request, spider, response.status)
if response.status in [301, 307] and 'Location' in response.headers:
redirected_url = urljoin(request.url, response.headers['location'])
redirected = request.replace(url=redirected_url)
return self._redirect(redirected, request, spider, response.status)
if isinstance(response, HtmlResponse):
interval, url = get_meta_refresh(response)
if url and interval < self.max_metarefresh_delay:
redirected = self._redirect_request_using_get(request, url)
return self._redirect(redirected, request, spider, 'meta refresh')
return response
(3) Теперь вы можете получить доступ к списку перенаправлений в вашем пауке с
request.meta['redirect_status']