Обработка ошибок

Правила обработки запросов

  • Если запрос выполнен успешно, то вызывается метод-обработчик, связанный с заданием по его имени.
  • Если запрос был нарушен из-за сетевой ошибки, то задание снова отправляется в очередь заданий.
  • Если произошла непредвиденная ошибка в обработчике задания, то обработка задания прекращается немедленно. Ошибка в обработчике не фатальна: она не влияет на работу обработчиков других заданий.

Сетевые ошибки

Сетевой ошибокй считаются следующие случаи: * произошла ошибка во время передачи данных, например, сервер отверг запрос на соеденине или оборвал связь до того, как данные были переданы или данные передавались слишком долго * данные были переданы, но 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.