Обработка ошибок¶
Правила обработки запросов¶
- Если запрос выполнен успешно, то вызывается метод-обработчик, связанный с заданием по его имени.
- Если запрос был нарушен из-за сетевой ошибки, то задание снова отправляется в очередь заданий.
- Если произошла непредвиденная ошибка в обработчике задания, то обработка задания прекращается немедленно. Ошибка в обработчике не фатальна: она не влияет на работу обработчиков других заданий.
Сетевые ошибки¶
Сетевой ошибокй считаются следующие случаи: * произошла ошибка во время передачи данных, например, сервер отверг запрос на соеденине или оборвал связь до того, как данные были переданы или данные передавались слишком долго * данные были переданы, но HTTP-статус ответа отличен от 2xx или 404
Cуществует ряд настроек, для задания критериев, по которым сетеовой запрос помечается как ошибочный.
Вы можете управлять таймаутами: timeout и connect_timeout. Для задания этих настроек вам нужно конструировать Task-обеъкт с помощью настроенного Grab-объекта:
g = Grab(timeout=5, connect_timeout=1, url='http://example.com')
t = Task('example', grab=g)
Вы можете указывать дополнительный список HTTP-статусов, которые будут считаться успешными:
t = Task('example', url='http://example.com', valid_status=(500, 501, 502))
Повторно выполнение заданий¶
Завершившееся сетевой ошибкой задание повторно отправляется в очередь заданий. Количество попыток зависит от атрибута Spider.network_try_limit и по умолчанию равно десяти. Номер попытки хранится в атрибуте Task.network_try_count. Если все попытки исчерпаны, то задание больше не добавляетя в очередь. Кроме того, если в пауке определён метод task_<имя задания>_fallback, то он вызывается и получает в качестве единственного аргумента Task-объект, невыполненного задания.
Также бывает, что хотя HTTP-статус не содержит ошибки, но данные ответа являются неверными, например, когда отправленная форма отображается ещё раз из-за неверно заполненного поля или когда сайт показывает каптчу или сообщение о том, что ваш IP забанен. В таких случаях нужно вручную (из метода-обработчика) отправить это задание ещё раз в очередь. Дабы избежать бесконечного добавления такого задания в очередь существует ещё один счётчик: Task.task_try_count и соответсвующее ему ограничение в пауке Spider.task_try_limit. Важное замечание, в случае использования task_try_count вы должны самостоятельно увеличивать его значение при повторной отправке задания в очередь:
def task_google(self, grab, task):
if captcha_found(grab):
yield Task('google', url=grab.config['url'], task_try_count=task.task_try_count + 1)
def task_google_fallback(self, task):
print 'Google is not happy with you IP address'
Статистика ошибок¶
После завершения работы паука, или даже во время его работы, вы можете получить суммарную информацию о количестве сделанных запросов и количестве различных ошибок с помощью метода Spider.render_stats.