Красивые проблемы с супом и юникодом

Я использую BeautifulSoup для анализа некоторых веб-страниц.

Иногда я сталкиваюсь с ошибкой «unicode hell», например:

Глядя на источник этой статьи на TheAtlantic.com [ http://www.theatlantic.com/education/archive/2013/10/why-are-hundreds-of-harvard-students-studying-ancient-chinese-philosophy/ 280356 / ]

Мы видим это в свойствах og: description meta:

<meta property="og:description" content="The professor who teaches&nbsp;Classical Chinese Ethical and Political Theory claims, &quot;This course will change your life.&quot;" /> 

Когда BeautifulSoup анализирует это, я вижу следующее:

 >>> print repr(description) u'The professor who teaches\xa0Classical Chinese Ethical and Political Theory claims, "This course will change your life."' 

Если я попробую кодировать его в UTF-8, как этот комментарий SO предлагает: https://stackoverflow.com/a/10996267/442650

 >>> print repr(description.encode('utf8')) 'The professor who teaches\xc2\xa0Classical Chinese Ethical and Political Theory claims, "This course will change your life."' 

Когда я думал, что все мои проблемы с юникодом находятся под контролем, я все еще не совсем понимаю, что происходит, поэтому я собираюсь задать несколько вопросов:

1- почему BeautifulSoup конвертирует &nbsp; to \xa0 [ \xa0 латинского символа]? Кодировка и заголовки на этой странице – UTF-8, я думал, что BeautifulSoup извлекает эти данные для кодирования? Почему он не был заменен на <space> ?

2- Существует ли общий способ нормализации пробелов для преобразования?

3- Когда я закодирован в UTF8, где \xa0 стал последовательностью \xc2\xa0 ?

Я могу unicodedata.normalize('NFKD',string) все через unicodedata.normalize('NFKD',string) чтобы помочь мне, где я хочу быть, – но я хотел бы понять, что не так, и избежать такой проблемы в будущем.

One Solution collect form web for “Красивые проблемы с супом и юникодом”

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

&nbsp; указывает неразрывный символ пробела . Это не заменяется пробелом, поскольку оно не представляет собой пробел; он представляет собой неразрывное пространство. Замена его пространством потеряла бы информацию: что там, где это место, движок текстового рендеринга не должен помещать разрыв строки.

Кодовая точка Unicode для неразрывного пространства – U + 00A0, которая написана в строке Unicode в Python как \xa0 .

Кодировка UTF-8 U + 00A0 представляет собой шестнадцатеричную последовательность двух байтов C2 A0 или записывается в строковое представление Python, \xc2\xa0 . В UTF-8 для чего-либо, кроме 7-битного набора ASCII, требуется два или более байтов для его представления. В этом случае самый старший бит – восьмой бит. Это означает, что он может быть представлен двухбайтовой последовательностью (в двоичном формате) 110xxxxx 10xxxxxx где x – это биты двоичного представления кодовой точки. В случае A0, то есть 10000000 , или при кодировании в UTF-8, 11000010 10000000 или C2 A0.

Многие люди используют &nbsp; в HTML, чтобы получить пробелы, которые не сворачиваются с помощью обычных правил свертывания пробелов HTML (в HTML все пробежки последовательных пробелов, вкладок и новых строк интерпретируются как одно пространство, если не применяется одно из правил white-space CSS ) но это не совсем то, для чего они предназначены; они должны использоваться для таких вещей, как имена, такие как «Mr. Miyagi», где вы не хотите, чтобы был разрыв строки между «мистером», и "Мияги". Я не уверен, почему он использовался в этом конкретном случае; это кажется неуместным здесь, но это больше проблема с вашим источником, а не с кодом, который его интерпретирует.

Теперь, если вам не очень нравится макет, поэтому вы не возражаете, выбирают ли алгоритмы компоновки текста как место для обертывания, но хотели бы интерпретировать это просто как обычное пространство, нормализация использования NFKD вполне разумна ответ (или NFKC, если вы предпочитаете предварительно сконфигурированные акценты для разложенных акцентов). Нормативы нормализации NFKC и NFKD, такие, что большинство символов, которые представляют по существу одно и то же семантическое значение в большинстве контекстов, расширяются. Например, лигатуры расширяются (ffi -> ffi), архаичные длинные символы преобразуются в s (s -> s), символы римских цифр расширяются в их отдельные буквы (Ⅳ -> IV) и неразрывное пространство преобразуется в нормальное пространство. Для некоторых символов нормализация NFKC или NFKD может потерять информацию, которая важна в некоторых контекстах: ℌ и ℍ оба будут нормализованы до H, но в математических текстах можно использовать для обозначения разных вещей.

  • Специальные национальные символы не будут .split () в Python
  • как разбить строку unicode на список
  • Python 3 smtplib отправляет с символами unicode
  • UnicodeDecodeError при перенаправлении в файл
  • преобразование строки unicode в python
  • Как удалить строку unicode из списка
  • разделение строки юникода на слова
  • chr () эквивалент, возвращающий объект байтов, в py3k
  • Python - лучший язык программирования в мире.