Нужна помощь с обработкой исключений Python - PullRequest
2 голосов
/ 15 февраля 2011

Вот код, с которым я сейчас работаю:

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, а я на python3, который, я думаю, urllib.error.URLError iirc. В любом случае, я знаю, что могу сделать, кроме URLError, и он должен работать (хотя мне интересно, нужно ли мне вместо этого делать urllib.error.URLError, поскольку это то, что он сообщает о моем), но как мне проверить, чтобы убедиться, что это из-за 104. Я хотел бы, чтобы он продолжал повторять запрос до тех пор, пока он не получит его, или, по крайней мере, не пытался бы это выполнить указанное количество раз, как бы я сделал это наиболее элегантно?

Из того, что я могу найти, ошибка 104 заключается в том, что мой локальный маршрутизатор не может обработать запрос и, как мне кажется, выходит из себя, потому что он не может обрабатывать запросы так быстро? Если у кого-то есть дальнейшее понимание того, что вызывает это, это тоже было бы полезно, но я не слишком обеспокоен.

Ответы [ 2 ]

1 голос
/ 15 февраля 2011

Взгляните на http://docs.python.org/py3k/library/urllib.error.html

Когда вы посмотрите на атрибут reason в исключении, вы сможете определить:

  1. Является ли атрибут причины экземпляром socket.error?
  2. Если это так, является ли значение этой ошибки 2-кортежем, причем первый элемент соответствует errno.ECONNRESET?
0 голосов
/ 15 февраля 2011

Во-первых, нет смысла использовать 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
...