Python 2 и Python 3 – форматы urllib

Мне очень надоело пытаться понять, почему этот код работает в Python 2, а не в Python 3. Я просто пытаюсь захватить страницу json, а затем проанализировать ее. Вот код в Python 2:

import urllib, json response = urllib.urlopen("http://reddit.com/.json") content = response.read() data = json.loads(content) 

Я думал, что эквивалентный код в Python 3 будет следующим:

 import urllib.request, json response = urllib.request.urlopen("http://reddit.com/.json") content = response.read() data = json.loads(content) 

Но это взрывается мне в лицо, потому что данные, возвращаемые read (), являются «байтами». Тем не менее, я не могу для жизни меня заставить его преобразовать в то, что json сможет анализировать. Я знаю из заголовков, что reddit пытается отправить utf-8 мне, но я не могу заставить байты декодироваться в utf-8:

 import urllib.request, json response = urllib.request.urlopen("http://reddit.com/.json") content = response.read() data = json.loads(content.decode("utf8")) 

Что я делаю не так?

Изменить: проблема в том, что я не могу получить данные в полезное состояние; даже если json загружает данные, часть которых не отображается, и я хочу иметь возможность печатать данные на экране.

Второе редактирование: похоже, проблема связана скорее с печатью, чем с парсингами. Ответ Алекса дает возможность сценарию работать в Python 3, установив IO в utf8. Но остается вопрос: почему код работает в Python 2, но не Python 3?

3 Solutions collect form web for “Python 2 и Python 3 – форматы urllib”

Вероятно, код, который вы публикуете, связан с неправильными операциями «вырезать и вставлять», потому что он явно неверен в обеих версиях ( f.read() терпит неудачу, потому что не определено f barename).

В Py3 ur = response.decode('utf8') отлично работает для меня, также как и json.loads(ur) . Возможно, неправильные копии и пасты повлияли на ваши попытки преобразования 2-в-3.

Зависит от вашей версии python, вы должны выбрать правильную библиотеку.

для python 3.5

 import urllib.request data = urllib.request.urlopen(url).read().decode('utf8') 

для python 2.7

 import urllib url = serviceurl + urllib.urlencode({'sensor':'false', 'address': address}) uh = urllib.urlopen(url) 

См. Этот ответ в другом вопросе, связанном с Юникодом.

Теперь: Python 3 str (который был типом Python 2 unicode ) – идеализированный объект, в том смысле, что он имеет дело с «символами», а не «байтами». Эти символы, которые должны использоваться для / из данных диска / сети, должны быть закодированы в / декодированы – из байтов с помощью «таблицы преобразования», также называемой кодовой страницей. Из-за разнообразия операционной системы Python исторически избегало догадываться, что такое кодировка; это меняется с годами, но по-прежнему остается принцип «перед лицом двусмысленности, отказаться от соблазна угадать».

К счастью, веб-сервер упрощает вашу работу. Ваш response выше должен предоставить вам всю дополнительную информацию:

 >>> response.headers['content-type'] 'application/json; charset=UTF-8' 

Таким образом, каждый раз, когда вы отправляете запрос на веб-сервер, проверяйте заголовок Content-Type на значение charset и декодируете данные запроса в Unicode (Python 3: bytes.decode(charset)str ), используя эту кодировку.

  • используя python urllib, как избежать не HTML-содержимого
  • Как получить значения динамического содержимого html с помощью Python
  • Ошибка ввода-вывода (ошибка сокета): Соединение отклонено
  • Python: почтовый запрос с файлами изображений
  • Вопрос Python 3.2
  • Python, противоположная функция urllib.urlencode
  • Как автоматически регистрировать фид Atom с помощью Python?
  • Как Google на Python с помощью urllib или запросов
  • Запросы python медленны
  • Выполнение запроса HTTP POST
  • Как загрузить веб-страницу, требующую имя пользователя и пароль?
  • Python - лучший язык программирования в мире.