需要帮助处理Python异常

2 投票
2 回答
4568 浏览
提问于 2025-04-16 11:51

这是我目前正在使用的代码:

url = locations[state]['url']
headers = {'User-Agent':'Firefox/3.6.13'}
req = urllib.request.Request(url, headers=headers)
try:
    resp = urllib.request.urlopen(req)
except:
    print('Caught error, trying again...')
    print('This should be handled better, I\'m sorry')
    time.sleep(2)
    resp = urllib.request.urlopen(req)

我遇到的问题,以及我真正关心的异常是,当我发出请求时,有时会出现这样的情况:

URLError: <urlopen error [Errno 104] Connection reset by peer>

这不是确切的错误信息,我觉得这可能是针对 Python 2.x 的 urllib/urllib2,而我使用的是 Python 3,我记得应该是 urllib.error.URLError。无论如何,我知道我可以用 except URLError 来处理这个问题,应该可以正常工作(不过我在想是不是应该用 urllib.error.URLError,因为我的报错信息是这个)。但是,我该如何测试确保这是因为错误代码 104 呢?我希望它能不断重试请求,直到成功,或者至少尝试指定的次数,我该怎么做才能做到这一点呢?

根据我找到的信息,错误 104 是因为我的本地路由器无法处理请求而出现的问题,我猜是因为它无法这么快处理请求?如果有人能进一步解释一下是什么导致这个问题,那也会很有帮助,不过我对此不是太担心。

2 个回答

-1

首先,在新的代码中其实没有必要使用 urllib,推荐使用 urllib2

根据我的理解,你想要在遇到错误代码104时才重试。通常在Python中是这样做的:

import time, urllib.request, urllib2.error
RETRY_DELAY = 2

# build req here
# ...

for x in range(10): # Always limit number of retries
  try:
    resp = urllib.request.urlopen(req)
  except urllib.error.URLError:
    if e.reason[0] == 104: # Will throw TypeError if error is local, but we probably don't care
      time.sleep(RETRY_DELAY)
    else:
      raise # re-raise any other error
  else:
    break # We've got resp sucessfully, stop iteration
1

你可以看看这个链接:http://docs.python.org/py3k/library/urllib.error.html

当你查看异常的 reason 属性时,你应该能判断:

  1. 这个 reason 属性是不是一个 socket.error 的实例?
  2. 如果是的话,这个错误的值是不是一个包含两个元素的元组,第一个元素对应 errno.ECONNRESET

撰写回答