python request.get() возвращает неправильно декодированный текст вместо UTF-8?

Когда тип содержимого сервера является "Content-Type: text/html". request.get() возвращает неверно закодированные данные. Где, как будто у меня есть тип содержимого явно как "Content-Type: text/html; charset = utf-8 ', Он возвращает правильные данные.

Когда мы использовали urllib.urlopen(), он возвращает правильные данные. Кто-нибудь заметил это раньше? почему request.get() ведет себя так?

Ответ 1

Из документации запросов:

Когда вы делаете запрос, Requests делает обоснованные предположения о кодировании ответа на основе заголовков HTTP. Текстовое кодирование, угаданное запросами, используется при доступе к r.text. Вы можете узнать, что использует кодировка запросов, и изменить ее, используя свойство r.encoding.

>>> r.encoding
'utf-8'
>>> r.encoding = 'ISO-8859-1'

Проверьте запросы на кодировку, используемые для вашей страницы, и если это не так, попробуйте заставить ее быть тем, который вам нужен.

Что касается различий между requests и urllib.urlopen - они, вероятно, используют разные способы угадать кодировку. Это все.

Ответ 2

Образованные предположения (упомянутые выше), вероятно, являются просто проверкой заголовка Content-Type, отправляемого сервером (вводящее в заблуждение использование образованного imho).

Для заголовка ответа Content-Type: text/html результат - ISO-8859-1 (по умолчанию для HTML4), независимо от анализа содержимого (т.е. по умолчанию для HTML5 - UTF-8).

Для заголовка ответа Content-Type: text/html; charset=utf-8 результат - UTF-8.

К счастью для нас, запросы используют библиотеку chardet, и это обычно работает достаточно хорошо (атрибут requests.Response.apparent_encoding), так что вы обычно хотите сделать:

r = requests.get("https://martin.slouf.name/")
# override encoding by real educated guess as provided by chardet
r.encoding = r.apparent_encoding
# access the data
r.text

Ответ 3

Предполагаемая кодировка содержимого по умолчанию для text/html - ISO-8859-1, в переводе с Latin-1 :( См. RFC-2854. UTF-8 был слишком молод, чтобы стать по умолчанию, он родился в 1993 году, примерно в то же время, что и HTML и HTTP.

Используйте .content для доступа к потоку байтов или .text для доступа к декодированному потоку Unicode. Если HTTP-сервер не заботится о правильной кодировке, значение .text может быть отключено.