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