Python/Mechanize中从ECONNRESET恢复

2 投票
1 回答
4277 浏览
提问于 2025-04-16 10:57

我有一个用Python和Mechanize写的大型批量下载应用,目标是下载大约20,000个文件。显然,这么大的下载器偶尔会遇到一些ECONNRESET错误。我知道怎么处理这些错误,但有两个问题:

  1. 我真的不想把每一个外部网页请求都放在一个try/catch块里。
  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)
    

    那我怎么知道Mechanize的内部状态是什么样的,如果在这里抛出了ECONNRESET?比如,我是否需要在重新尝试代码之前调用browser.back()?从这种错误中恢复的正确方法是什么?

编辑:接受的答案中的解决方案确实有效,在我的情况下实现起来也不算太难。不过,我仍然对是否有一种错误处理机制能更快捕捉错误感兴趣。

1 个回答

2

也许可以把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)

撰写回答