Как отловить ошибку 404 в urllib.urlretrieve - PullRequest
26 голосов
/ 21 августа 2009

Справочная информация: я использую urllib.urlretrieve, в отличие от любой другой функции в модулях urllib*, из-за поддержки функции ловушки (см. reporthook ниже) .. которая используется для отобразить текстовый индикатор выполнения. Это Python> = 2.6.

>>> urllib.urlretrieve(url[, filename[, reporthook[, data]]])

Однако urlretrieve настолько глуп, что не оставляет возможности определить состояние HTTP-запроса (например: 404 или 200?).

>>> fn, h = urllib.urlretrieve('http://google.com/foo/bar')
>>> h.items() 
[('date', 'Thu, 20 Aug 2009 20:07:40 GMT'),
 ('expires', '-1'),
 ('content-type', 'text/html; charset=ISO-8859-1'),
 ('server', 'gws'),
 ('cache-control', 'private, max-age=0')]
>>> h.status
''
>>>

Каков наиболее известный способ загрузки удаленного файла HTTP с поддержкой в ​​виде хуков (для отображения индикатора выполнения) и приличной обработки ошибок HTTP?

Ответы [ 3 ]

28 голосов
/ 21 августа 2009

Проверьте urllib.urlretrieve полный код:

def urlretrieve(url, filename=None, reporthook=None, data=None):
  global _urlopener
  if not _urlopener:
    _urlopener = FancyURLopener()
  return _urlopener.retrieve(url, filename, reporthook, data)

Другими словами, вы можете использовать urllib.FancyURLopener (это часть общедоступного API urllib). Вы можете переопределить http_error_default, чтобы обнаружить 404 с:

class MyURLopener(urllib.FancyURLopener):
  def http_error_default(self, url, fp, errcode, errmsg, headers):
    # handle errors the way you'd like to

fn, h = MyURLopener().retrieve(url, reporthook=my_report_hook)
14 голосов
/ 04 февраля 2010

Вы должны использовать:

import urllib2

try:
    resp = urllib2.urlopen("http://www.google.com/this-gives-a-404/")
except urllib2.URLError, e:
    if not hasattr(e, "code"):
        raise
    resp = e

print "Gave", resp.code, resp.msg
print "=" * 80
print resp.read(80)

Редактировать: Обоснование здесь заключается в том, что если вы не ожидаете исключительного состояния, это исключение для него, и вы, вероятно, даже не думали об этом - поэтому вместо того, чтобы позволить своему коду продолжить работу, пока она не удалась, поведение по умолчанию - вполне разумно - запретить его выполнение.

2 голосов
/ 21 августа 2009

Метод retreive объекта URL Opener поддерживает reporthook и создает исключение для 404.

http://docs.python.org/library/urllib.html#url-opener-objects

...