Я пытаюсь работать с веб-сайтом Центрального банка Бразилии.
Моя вещь заключается в получении данных из раздела уведомления, когда это связано с "свопом" (центральный банк продает доллары США на местном рынке для контроля обесценения национальных денег).
У меня много проблем с API и кодировкой. Это часть сайта, на котором мы можем найти все отчеты: http://www.bcb.gov.br/pre/normativos/busca/buscaNormativo.asp?tema=&startRow=0&refinadorTipo=&refinadorRevogado=&tipo=P&tipoDocumento=0&numero = & conteudo = & dataInicioBusca = 13% 2F6% 2F2018 & dataFimBusca = 16% 2F6% 2F2018
Когда я пытаюсь получить html с главной страницы, я получил следующее:
Divulga как condi\u00f5es deerta p\u00fablica для реализаций \u00e3o de opera\u00e7\u00f5es de swap
но это должно быть:
Divulga в качестве условий для работы по обмену операциями.
Я пробовал этот сводный код:
import requests
from bs4 import BeautifulSoup as bs
url = 'http://www.bcb.gov.br/pre/normativos/busca/buscaSharePoint.asp?conteudo=swap&startRow=0'
data = requests.get(url)
bsObj = bs(data.content, 'lxml')
bsObj.find("div") #returned the example, with the wrong encode
bsObj = bs(data.content, 'lxml', from_encoding='latin-1')
bsObj.find("div") #the same
bsObj = bs(data.content, 'lxml', from_encoding='utf-8')
bsObj.find("div") #the same
Кто-нибудь понимает, что происходит?
Символом ç
является U + 00e7, а õ
- U + 00F5 и т.д. Это всего лишь два разных представления одной и той же строки. Итак, пока я просто угадываю вашу проблему, учитывая неполную информацию, я думаю, что это обоснованное предположение...
Если вы print
строку, вы увидите читаемую человеком версию с condições
и т.д. (Если только ваш Python и консоль не настроены на правильное condições
друг с другом, но если вы используете Python 3.6 или новее и современная версия Linux, MacOS или Windows, это вряд ли будет проблемой).
Но если вы просто оцениваете строку в интерактивном интерпретаторе, вы получаете представление, удобное для программистов, а не дружественное к человеку.
Например:
>>> s = 'Divulga as condições de oferta pública para a realização de operações de swap.'
>>> print(s)
Divulga as condições de oferta pública para a realização de operações de swap.
>>> s
'Divulga as condi\u00e7\u00f5es de oferta p\u00fablica para a realiza\u00e7\u00e3o de opera\u00e7\u00f5es de swap'
Последнее хорошо, потому что вы можете копировать и вставлять его в исходный код в виде строкового литерала, и потому, что он будет работать даже на плохо сконфигурированном терминале, но он не так хорош для чтения.
Техническая разница заключается в том, что print
вызывает str
, а при вычислении строки в интерактивном интерпретаторе без repr
вызовов на print
.
Между тем: большинство веб-сайтов определяют их кодировку (по крайней мере, одним из трех способов...), и в этом случае requests
могут автоматически декодировать вещи правильно, если вы используете text
вместо content
:
bsObj = bs(data.text, 'lxml')
Единственная причина сделать что-то другое, кроме этого, - это нарушение сайта и смущение requests
.
Если вы просто используете data.content
, BeautifulSoup использует библиотеку под названием unicodedammit
чтобы эвристически попытаться угадать правильную кодировку.
Если вы используете data.content
и from_encoding
, вам нужно знать правильную кодировку, чтобы вы могли ее передать. Это полезно в качестве последнего средства, но не должно быть первым, к чему вы обращаетесь.
Я подозреваю, что from_encoding=Latin-1
и from_encoding=UTF-8
фактически не делают то же самое. Они, конечно, не должны. Скорее всего, первый дал вам другую неправильную кодировку, но вы просто не заметили, что это было иначе. Может быть, что-то вроде этого:
'Divulga as condi\u00c3\u00a7\u00c3\u00b5es de oferta p\u00c3\u00bablica para a realiza\u00c3\u00a7\u00c3\u00a3o de opera\u00c3\u00a7\u00c3\u00b5es de swap.'
Это может выглядеть не совсем по-другому, если вы не знаете таблицу Unicode размером 100 000 символов наизусть, в шестнадцатеричном формате, но если вы ее print
, вы увидите, что это совсем другое:
Divulga as condições de oferta pública para a realização de operações de swap.