Я пытаюсь разобрать веб-страницу, используя красивый парсер Python для супа, и столкнулся с проблемой.
Заголовок HTML, который мы получаем от них, объявляет набор символов utf-8, поэтому Beautiful Soup кодирует весь документ в utf-8, и теги HTML действительно кодируются в UTF-8, поэтому мы получаем хорошо структурированную HTML-страницу.
Проблема в том, что этот глупый веб-сайт вставляет основной текст в кодировке gb2312 на страницу, которая обрабатывается как utf-8 красивым супом. Есть ли способ преобразовать текст из этого состояния "gb2312, притворяющегося utf-8", в "правильное выражение набора символов в utf-8?"
Ответ 1 · рейтинг 1 · BrenBarn
Самый простой способ - дважды проанализировать страницу, один раз как UTF-8 и один раз как GB2312. Затем извлеките соответствующий раздел из синтаксического анализа GB2312.
Я мало что знаю о GB2312, но, посмотрев его, он, по крайней мере, согласуется с ASCII по основным буквам, цифрам и т. Д. Таким образом, вы все равно должны иметь возможность анализировать структуру HTML с помощью GB2312, что, надеюсь, даст вам достаточно информацию для извлечения нужной детали.
На самом деле это может быть единственный способ сделать это. Как правило, текст в кодировке GB2312 не будет допустимым UTF-8, поэтому попытка декодировать его как UTF-8 должна привести к ошибкам. В документации BeautifulSoup говорится:
В редких случаях (обычно когда документ UTF-8 содержит текст, написанный в совершенно другой кодировке) единственным способом получить Unicode может быть замена некоторых символов специальным символом Unicode "СИМВОЛ ЗАМЕНЫ" (U+FFFD, �). Если для этого потребуется Unicode, Dammit установит для атрибута .contains_replacement_characters значение True в объекте UnicodeDammit или BeautifulSoup.
Это звучит так, как будто BeautifulSoup просто игнорирует ошибки декодирования и заменяет ошибочные символы на U+FFFD. Если это так (т. е. если ваш документ имеет contains_replacement_characters == True), то нет никакого способа получить исходные данные из документа после его декодирования как UTF-8. Вам придется сделать что-то вроде того, что я предложил выше, дважды декодируя весь документ разными кодеками.