在Python/Mechanize中从EconReset恢复

在Python/Mechanize中从EconReset恢复,python,error-handling,tcp,mechanize,Python,Error Handling,Tcp,Mechanize,我有一个用Python/Mechanize编写的大容量下载应用程序,目标是下载大约20000个文件。显然,任何这么大的下载程序偶尔都会遇到一些ECONNRESET错误。现在,我知道如何处理,但有两个问题: 我真的不想把每个出站web调用都包装在一个try/catch块中 即使我这样做了,在异常抛出后知道如何处理错误也会有麻烦。如果代码是 data = browser.response().read() 那么我就确切地知道如何处理它,即: data = None while (data == N

我有一个用Python/Mechanize编写的大容量下载应用程序,目标是下载大约20000个文件。显然,任何这么大的下载程序偶尔都会遇到一些
ECONNRESET
错误。现在,我知道如何处理,但有两个问题:

  • 我真的不想把每个出站web调用都包装在一个try/catch块中
  • 即使我这样做了,在异常抛出后知道如何处理错误也会有麻烦。如果代码是

    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
    ,我怎么知道Mechanize的内部状态是什么样的呢?例如,在重试代码之前是否需要调用
    browser.back()
    ?从这种错误中恢复过来的正确方法是什么


  • 编辑:被接受的答案中的解决方案肯定是有效的,在我的例子中,结果证明它并不难实现。然而,我在学术上仍感兴趣的是,是否有一种错误处理机制可以更快地捕获错误。

    也许可以尝试一下。除了命令链中更高层的块:

    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)
    

    如果没有更好的错误处理方法,我认为这是“核选项”。谢谢@查尔斯·彭斯:你可以让它变得更智能,但这需要在每个web调用周围放置try..块,并根据具体情况处理每个错误。。。我怀疑还有比这更好的办法,因为只有程序员才能决定在任何给定点发生故障时应该采取什么适当的措施。事实证明,这比我想象的更容易实现。谢谢大家@查尔斯·彭斯:你可以缓存/记忆中间步骤的结果,这样当你第二次调用
    download\u file(url)
    时,成功的网络调用可以被跳过。