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
может быть отключено.