urllib для питона 3

Этот код в Python3 является проблематичным:

import urllib.request
fhand=urllib.request.urlopen('http://www.py4inf.com/code/romeo.txt')
print(fhand.read())

Его вывод:

b'But soft what light through yonder window breaks'
b'It is the east and Juliet is the sun'
b'Arise fair sun and kill the envious moon'
b'Who is already sick and pale with grief'

Почему я получил b'...'Could Что я мог сделать, чтобы получить правильный ответ?

Правильный текст должен быть

But soft what light through yonder window breaks
It is the east and Juliet is the sun
Arise fair sun and kill the envious moon
Who is already sick and pale with grief

4 ответа

b'...' является байтовой строкой: массив байтов, а не настоящая строка.

Чтобы преобразовать в реальную строку, используйте

fhand.read().decode()

При этом используется кодировка по умолчанию "UTF-8". Для кодирования ASCII используйте

fhand.read().decode("ASCII")

например

Как сказано в документации, urlopen возвращает объект, чей read Метод дает вам последовательность байтов, а не последовательность символов. Чтобы преобразовать байты в печатные символы, что вам и нужно, вам необходимо применить decode метод, использующий кодировку байтов.

Причина, по- видимому, имеет смысл в том, что код Python, выбранный по умолчанию для отображения байтов, оказывается правильным или, по крайней мере, совпадает с правильным для этих символов.

Чтобы сделать это правильно, вы должны read().decode(encoding) где encoding это значение кодировки из Content-Type HTTP-заголовок, доступный через HTTPResponse объект (то есть fhandв вашем коде). Если нет Content-Type заголовок или, если он не указывает кодировку, вы просто угадываете, какую кодировку использовать, но для типичного английского текста это не имеет значения, и во многих других случаях это, вероятно, будет UTF-8.

Python 3 различает последовательности байтов и строки. "B" перед строкой говорит вам, что urllib вернул содержимое в виде "сырых" байтов. Возможно, стоит прочитать ситуацию с 3 байтами / строками в python, но в основном вы вернули правильный текст. Если вы не хотите, чтобы результат был в байтах, вам просто нужно преобразовать его обратно в "настоящую" строку питона.

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

>>> import requests
>>> r = requests.get('http://www.py4inf.com/code/romeo.txt')
>>> print(r.text)
But soft what light through yonder window breaks
It is the east and Juliet is the sun
Arise fair sun and kill the envious moon
Who is already sick and pale with grief

То же самое с urllib.request и предполагаемый UTF-8 кодирование:

>>> from urllib.request import urlopen
>>> r = urlopen('http://www.py4inf.com/code/romeo.txt')
>>> print(r.read().decode('UTF-8'))
But soft what light through yonder window breaks
It is the east and Juliet is the sun
Arise fair sun and kill the envious moon
Who is already sick and pale with grief
Другие вопросы по тегам