Странное поведение с urllib.request.urlopen в Ubuntu 18.04

#python-3.x #urllib

#python-3.x #urllib

Вопрос:

Я работал с онлайн-классом по python с помощью Coursera (это не домашнее задание), и у меня возникли проблемы с urllib.request.urlopen для некоторых URL-адресов. Для URL-адреса, жестко заданного в приведенном ниже коде, время ожидания команды urllib.request.urlopen(serviceurl, context=ctx).read().decode() истекло. Если используется другой URL… скажем http://www.woot.com если используемые данные будут возвращены.

Я пробовал это на двух отдельных компьютерах Ubuntu в моем местоположении, оба работают под управлением 18.04 (с 3.6.7 по умолчанию) и 3.7.3 через Anaconda. Я даже переустановил Ubuntu с теми же результатами.

Как ни странно, если я включаю параметр времени ожидания (например, urllib.request.urlopen(serviceurl, timeout= 1, context=ctx).read().decode()), возвращаются данные.

Кроме того, эта программа успешно запускается (независимо от url) без параметра timeout на macbook air под управлением версии 3.6.4

 import urllib.request
import ssl


# Ignore SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

address = input('Enter Locaton: ')
if len(address) < 1:
    serviceurl = 'http://py4e-data.dr-chuck.net/comments_42.xml?'
else:
    serviceurl = address

s = urllib.request.urlopen(serviceurl, context=ctx).read().decode()
print(s)

  

Кажется, я единственный, у кого есть эта проблема, и это ставит меня в тупик. Я только начинаю знакомиться с python (C, C #, Java более знакомы). Любые идеи будут оценены.

Ответ №1:

Ответил (я думаю) на мой собственный вопрос. Похоже, веб-сайту не нравятся сокеты IP6. Удалось отследить зависание до socket.py . Первый адрес, используемый при создании соединения, — это IP6-адрес и порт, которые ничего не возвращают. Добавление тайм-аута привело к тому, что код выбрал следующий адрес и порт из списка, который был IP4, и это сработало. На данный момент я отключил IP6 в Ubuntu 18.04, чтобы принудительно использовать IP4.