Я пытаюсь очистить веб-сайт на предмет неработающих ссылок, пока у меня есть этот код, который успешно выполняет вход в систему и сканирует сайт, но он записывает только коды состояния HTTP 200:
class HttpStatusSpider(scrapy.Spider):
name = 'httpstatus'
handle_httpstatus_all = True
link_extractor = LinkExtractor()
def start_requests(self):
"""This method ensures we login before we begin spidering"""
# Little bit of magic to handle the CSRF protection on the login form
resp = requests.get('http://localhost:8000/login/')
tree = html.fromstring(resp.content)
csrf_token = tree.cssselect('input[name=csrfmiddlewaretoken]')[0].value
return [FormRequest('http://localhost:8000/login/', callback=self.parse,
formdata = {'username': 'mischa_cs',
'password': 'letmein',
'csrfmiddlewaretoken': csrf_token},
cookies = {'csrftoken': resp.cookies['csrftoken']})]
def parse(self, response):
item = HttpResponseItem()
item['url'] = response.url
item['status'] = response.status
item['referer'] = response.request.headers.get('Referer', '')
yield item
for link in self.link_extractor.extract_links(response):
r = Request(link.url, self.parse)
r.meta.update(link_text=link.text)
yield r
документы и этиответы наводят меня на мысль, что handle_httpstatus_all = True
должен вызывать scrapy для передачи ошибочных запросов моему методу parse
, но пока мне не удалось их захватить.
Я также экспериментировал с handle_httpstatus_list
и пользовательским обработчиком errback
в другой итерации кода.
Что мне нужно изменить, чтобы фиксировать коды ошибок HTTP, с которыми сталкивается scrapy?
Я удалил allowed_domains = ['localhost']
без каких-либо изменений в поведении
Я вставил allowed_domains = ['localhost']
обратно после того, как паук попал на tripadvisor: 2018-12-17 19:29:09 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.tripadvisor.co.uk/Restaurants-g186364-c31-zfp5-Sheffield_South_Yorkshire_England.html>
хорошо, теперь мы столкнулись с другой проблемой? Пожалуйста проверьте мой ответ
handle_httpstatus_list
можно определить на уровне паука, но handle_httpstatus_all
можно определить только на уровне Request
, включая его в аргументе meta
.
Я бы по-прежнему рекомендовал использовать errback
для этих случаев, но если все находится под контролем, это не должно создавать новых проблем.
Ах, очень интересно. Это различие легко не заметить, и теперь я вижу, как записываются коды 4xx. Не уверен, что 5xx попадают в плен. Следующий шаг - попробовать errback
.
Рад, что помог вам получить нужные HTTP-запросы.
Итак, я не знаю, правильный ли это способ scrapy, но он позволяет мне обрабатывать все коды состояния HTTP (включая 5xx).
Я отключил HttpErrorMiddleware
, добавив этот фрагмент в settings.py
моего проекта scrapy:
SPIDER_MIDDLEWARES = {
'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware': None
}
Конечно, я бы сказал, что это хорошее решение, но, конечно, только для вашего проекта, я не думаю, что это можно было бы рекомендовать в проекте с большим количеством пауков, где нам нужно отключить это только для некоторых пауков или даже запросов.
пожалуйста, удалите аргумент
allowed_domains
, он не нужен, и он также может фильтровать ваши запросы, возможно, в этом проблема