2010-12-10 2 views
0

Я новичок в python и пытаюсь использовать urllib2/lxml для извлечения и анализа страницы. Кажется, что все работает нормально, за исключением того, что проанализированная страница, открытая в моем браузере, кажется, содержит в себе странные символы. Я предполагаю, что это проблема синтаксического анализа unicode/lxml. Когда я получаю текстовое содержимое элемента, используя .text_content(), и печатаю его, я получаю такие вещи, как «sometext \ 342 \ 200 \ 223 moretext» на исходной странице, это показывает как «sometext - moretext»Проблемы с кодировкой urllib2/lxml

Может ли кто-нибудь мне сказать:
1. Что происходит?
2. Как его исправить?
3. Где я могу узнать о таких проблемах с кодировкой?

Спасибо!

+0

Не могли бы вы привести пример? Либо код, либо точные результаты, а не просто «такие вещи, как« blabla »» или, желательно, оба. Кроме того, мы говорим о python 2 или 3? –

+0

вы можете вставить код и показать, что именно происходит? –

ответ

2

Что идут что веб-сайт использует «endash», который немного длиннее (и тот, который вы должны использовать в диапазонах, например 40-56). Да, тире - это целая наука для себя).

В Юникоде энсташ имеет код U + 2013. Числа, которые вы получаете, \ 342 \ 200 \ 223 - это восьмеричное представление кодировки UTF-8 этого кодового пункта. Почему вы получаете восьмеричное я не знаю, я получаю hex, поэтому на моем компьютере это выглядит как «\ xe2 \ x80 \ x93». Но это не имеет значения, это просто репрезентация. Номера одинаковы.

Что вы, вероятно, должны сделать, это как можно скорее декодировать строку HTML, которую вы получаете в unicode. Заголовки, которые вы возвращаете, когда вы забираете страницу, должны сообщить вам, какую кодировку она использует (хотя это, видимо, UTF8 здесь), довольно просто извлечь эти данные из заголовков, вы увидите это при распечатке заголовков.

Вы затем расшифровать HTML данных:

htmldata = htmldata.decode(<the encoding you found in the headers>) 
+0

Должны ли данные быть оставлены как unicode при передаче его другим программам? В настоящее время я сериализую данные, используя trift/pb (и его более поздние чтения с помощью программ C/C++, не поддерживающих unicode), что лучший способ справиться с этим? Можно ли свободно конвертировать между словами ISO-8859-1 и UTF-8? То есть, если программы на C++ портируются, чтобы быть в курсе, и ожидаете, что все входные данные в UTF-8, это было бы лучше? Спасибо! –

+0

@ Токи Том: см. Http://docs.python.org/howto/unicode.html#tips-for-writing-unicode-aware-programs советы по написанию программ, поддерживающих юникод. UTF-8 может выражать все кодовые точки Юникода (их более миллиона). См. Http://en.wikipedia.org/wiki/UTF-8. ISO-8859-1 может выражать 256 кодовых точек. См. Http://en.wikipedia.org/wiki/ISO/IEC_8859-1. Кодовые точки между U + 0000 и U + 00FF сопоставляются с одинаковыми значениями байтов как в UTF-8, так и в ISO-8859-1, поэтому преобразование из ISO-8859-1 в UTF-8 на самом деле является только отображением идентичности. Но не все UTF-8 могут быть декодированы в Юникод и перекодированы как ISO-8859-1. – unutbu

+0

@ Токи Том: Другие «программы» нет. Вы не можете оставить его как Юникод. Unicode - это * не * способ кодирования данных.Если вы хотите обменивать данные Unicode с одного программного обеспечения на другое, вам необходимо закодировать его с помощью кодировки, например UTF8 или Latin-1. При отправке его на другие функции Python, да, вы можете сохранить его как Unicode. –

0

Вам в основном нужно помнить о вопросах Юникода в двух точках в процессе:

  1. Получить ответ в строку Юникода, nicely explained here on SO
  2. Укажите подходящую кодировку при выводе строки

-

# from an lxml etree 
etree.tostring(root, encoding='utf-8', xml_declaration=False) 

# from a unicode string 
x.encode('utf-8') 
Смежные вопросы