Как узнать правильную кодировку при использовании BeautifulSoup?

В python3 и beautifulsoup4 я хочу получить информацию с веб-сайта после выполнения запросов. Я сделал так:

import requests
from bs4 import BeautifulSoup

req = requests.get('https://sisgvarmazenamento.blob.core.windows.net/prd/PublicacaoPortal/Arquivos/201901.htm').text

soup = BeautifulSoup(req,'lxml')

soup.find("h1").text
'\r\n                        CÃ\x82MARA MUNICIPAL DE SÃ\x83O PAULO'

Я не знаю, что такое кодировка, но это сайт с бразильским португальским языком, поэтому он должен быть utf-8 или latin1.

Пожалуйста, есть ли способ узнать, какая кодировка правильная?

А потом правильно ли BeautifulSoup читает эту кодировку?

Посмотрите: Как определить кодировку текста?

Ugo T. 30.05.2019 22:44
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
240
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Когда вы используете запросы, вы можете использовать функцию кодирование, например:

req = requests.get('https://sisgvarmazenamento.blob.core.windows.net/prd/PublicacaoPortal/Arquivos/201901.htm')

encoding = req.encoding
text = req.content

decoded_text = text.decode(encoding)

Спасибо @simonjansson. Сейчас ищу как правильно прочитать кодировку ISO-8859-1

Reinaldo Chaves 30.05.2019 23:06

Большое спасибо @simonjansson, но я все еще продолжаю делать ошибки. После приведенных выше команд я сделал: суп = BeautifulSoup(decoded_text, "lxml")

Reinaldo Chaves 30.05.2019 23:25

Это результат: soap.find("h1") -> <h1> CÃMARA MUNICIPAL DE SÃO PAULO<br/></h1>

Reinaldo Chaves 30.05.2019 23:26

Я использую Ubuntu, это может быть?

Reinaldo Chaves 30.05.2019 23:26

В один момент я заметил, что текст на моем экране отображается неправильно, но когда я скопировал его, он был правильным ...

Reinaldo Chaves 30.05.2019 23:27

Да, я думаю, это зависит от того, какой язык у вас на Ubuntu :)

simonjansson 30.05.2019 23:33

Использование: суп.найти('h1') - Не: суп.найти('h1').текст

simonjansson 30.05.2019 23:35

Спасибо @simonjansson, но ошибка сохраняется: CÃMARA MUNICIPAL DE SÃO PAULO

Reinaldo Chaves 31.05.2019 17:20

И когда сохраненный результат также как CSV

Reinaldo Chaves 31.05.2019 17:21
Ответ принят как подходящий

Запросы определяют кодировку как это:

When you receive a response, Requests makes a guess at the encoding to use for decoding the response when you access the Response.text attribute. Requests will first check for an encoding in the HTTP header, and if none is present, will use chardet to attempt to guess the encoding.

The only time Requests will not do this is if no explicit charset is present in the HTTP headers and the Content-Type header contains text. In this situation, RFC 2616 specifies that the default charset must be ISO-8859-1. Requests follows the specification in this case. If you require a different encoding, you can manually set the Response.encoding property, or use the raw Response.content.

Проверка заголовков запроса показывает, что действительно «в заголовках HTTP нет явного набора символов, а заголовок Content-Type содержит текст»

>>> req.headers['content-type']
'text/html'

Таким образом, запросы точно соответствуют стандарту и расшифровываются как ISO-8859-1 (latin-1).

В содержимом ответа указывается кодировка:

<META http-equiv = "Content-Type" content = "text/html; charset=utf-16">

однако это неправильно: декодирование как UTF-16 дает моджибаке.

chardet правильно определяет кодировку как UTF-8.

Итак, резюмируя:

  • нет общего способа определения кодировки текста с полной точностью
  • в данном конкретном случае правильной кодировкой является UTF-8.

Рабочий код:

>>> req.encoding = 'UTF-8'
>>> soup = bs4.BeautifulSoup(req.text,'lxml')
>>> soup.find('h1').text
'\r\n                        CÂMARA MUNICIPAL DE SÃO PAULO'

Другие вопросы по теме