Восстановление из ECONNRESET в Python / Mechanize - PullRequest
2 голосов
/ 31 января 2011

У меня есть большое приложение для массовой загрузки, написанное на Python / Mechanize, с целью загрузить что-то вроде 20 000 файлов.Ясно, что любой такой большой загрузчик иногда может столкнуться с некоторыми ECONNRESET ошибками.Теперь я знаю, как обрабатывать каждого из них в отдельности , но с этим есть две проблемы:

  1. Я бы действительно не хотел оборачивать каждый исходящий веб-вызов в попытку /Блок захвата.
  2. Даже если бы я это сделал, возникла проблема с пониманием того, как обрабатывать ошибки после того, как возникло исключение.Если код просто

    data = browser.response().read()
    

    , то я точно знаю, как с ним справиться, а именно:

    data = None
    while (data == None):
        try:
            data = browser.response().read()
        except IOError as e:
            if e.args[1].args[0].errno != errno.ECONNRESET:
                raise
            data = None
    

    , но если это просто случайный экземпляр

    browser.follow_link(link)
    

    тогда откуда мне знать, как выглядит внутреннее состояние Механизации, если где-то здесь выбросить ECONNRESET?Например, мне нужно позвонить browser.back(), прежде чем я попробую код еще раз?Как правильно исправить ошибку такого рода?

РЕДАКТИРОВАТЬ: Решение в принятом ответе, безусловно, работает, и в моем случае это оказалось не так сложно реализовать.Однако я по-прежнему заинтересован в том, чтобы узнать, есть ли механизм обработки ошибок, который может привести к более быстрому отлову ошибок.

1 Ответ

2 голосов
/ 31 января 2011

Возможно поместите блок try..except выше в цепочке команд:

import collections
def download_file(url):
    # Bundle together the bunch of browser calls necessary to download one file.
    browser.follow_link(...)
    ...
    response=browser.response()
    data=response.read()

urls=collections.deque(urls)

while urls:
    url=urls.popleft()
    try:
        download_file(url)
    except IOError as err:
        if err.args[1].args[0].errno != errno.ECONNRESET:
            raise
        else:
            # if ECONNRESET error, add the url back to urls to try again later
            urls.append(url)
...