Апр 10 2011

Python и urllib

Столкнулся с неожиданной проблемой при использовании библиотеки urllib (язык Python 3).

Допустим, нужно получить html-код документа, лежащего по определённому адресу. Для этого предназначена функция urllib.request.urlopen(url), возвращающая объект, имеющий интерфейс файла (т.е. поддерживающий те же функции, что и обычные файловые объекты). Далее можно просто прочитать из него текст в соответствующей кодировке: fileobj.read().decode(‘utf-8’), где fileobj — объект, возвращённый функцией urlopen().

При возникновении ошибки при открытии url функция urlopen() вызывает исключение. Поэтому его нужно обработать и повторять попытку открытия url до тех пор, пока операция не завершится без вызова исключения:

while 1:
  try:
    html = urllib.request.urlopen(url).read().decode('utf-8')
  except: print('Url Open Error') #Здесь можно записывать сообщения об ошибке в консоль или в лог
  else:
    break

Однако, проблема состоит в том, что urlopen() не всегда вызывает исключение. Если сервер не отвечает, она просто висит, полностью блокируя работу программы. При этом, при перезапуска программы вручную, документ нормально открывается. Поэтому в качестве параметра ей нужно передавать ещё и величину тайм-аута в секундах:

while 1:
  try:
    html = urllib.request.urlopen(url, timeout = 10).read().decode('utf-8')
  except: print('Url Open Error') #Здесь можно записывать сообщения об ошибке в консоль или в лог
  else:
    break

Теперь всё работает правильно.

  • http://progras.ru Борис

    Спасибо!
    Написал программу для сохранения прогноза погоды в базе данных. Написал давно и все забыл. Решил перейти на Python 3 и получил ошибку в json.loads()
    Оказалось, что нужно было добавить .decode(‘utf-8’) к read.

  • arktur04

    Я не являюсь профессиональным питонистом, но, насколько я знаю, Python 3 в настоящее время мало используется. Отсутствие обратной совместимости сыграло с ним злую шутку, и сейчас самая популярная ветка Python 2.7