2012-06-16 5 views
8

У меня есть эта проблема, пытаясь получить все текстовые узлы в документе HTML с помощью lxml, но я получаю UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 8995: ordinal not in range(128). Однако, когда я пытаюсь выяснить тип кодирования этой страницы (encoding = chardet.detect(response)['encoding']), он говорит, что это utf-8. Кажется странным, что на одной странице есть utf-8 и ascii. На самом деле это:UnicodeEncodeError при извлечении url

fromstring(response).text_content().encode('ascii', 'replace') 

решает проблему.

Вот это мой код:

from lxml.html import fromstring 
import urllib2 
import chardet 
request = urllib2.Request(my_url) 
request.add_header('User-Agent', 
        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)') 
request.add_header("Accept-Language", "en-us") 
response = urllib2.urlopen(request).read() 

print encoding 
print fromstring(response).text_content() 

Выход:

utf-8 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 8995: ordinal not in range(128) 

Что я могу сделать, чтобы решить эту проблему ?. Имейте в виду, что я хочу сделать это с помощью нескольких других страниц, поэтому я не хочу кодировать на индивидуальной основе.

UPDATE:

Может быть, есть что-то еще происходит. Когда я запускаю этот скрипт на терминале, я получаю правильный вывод, но когда запускаю его внутри SublimeText, я получаю UnicodeEncodeError ... ¿?

UPDATE2:

Это также происходит, когда я создаю файл с этим выходом. .encode('ascii', 'replace') работает, но я хотел бы иметь более общее решение.

С уважением

+1

Вызывает ли 'print u '\ u00A9 внутри вашего скрипта ошибку? – jfs

+0

Да.UnicodeEncodeError: кодек ascii не может кодировать символ u '\ xa9' в позиции 0: порядковый не в диапазоне (128) :-) –

+0

вы можете установить PYTHONIOENCODING любой кодировке символов, которую SublimeText принимает. – jfs

ответ

5

Можете ли вы попробовать обернуть свою строку с помощью функции repr()? This article может помочь.

print repr(fromstring(response).text_content()) 
+0

Это прекрасно работает в Sublime Text, а также в терминале. Наверное, это рабочий день. Благодаря! –

0

Основываясь на своем первом обновлении, я бы сказал, что терминал сказал Python для вывода UTF-8 и SublimeText дал понять, что ожидает ASCII. Поэтому я думаю, что решение будет заключаться в поиске правильных настроек в SublimeText.

Однако, если вы не можете изменить то, что SublimeText ожидает, лучше использовать функцию encode, как вы уже делали в отдельной функции.

def smartprint(text) : 
    if sys.stdout.encoding == None : 
     print text 
    else : 
     print text.encode(sys.stdout.encoding , 'replace') 

Вы можете использовать эту функцию вместо print. Имейте в виду, что вывод вашей программы при запуске в SublimeText отличается от Terminal. Из-за символов replace акцентированные символы теряют свои акценты, когда этот код запускается в SublimeText, например. é будет отображаться как e.

3

Насколько выписывая в файл, как сказал в своем редактировании, я рекомендовал бы открыть файл с модулем кодеков:

import codecs 
output_file = codecs.open('filename.txt','w','utf8') 

не знаю SublimeText, но это, кажется, попробуйте прочитать ваш вывод как ASCII, следовательно, ошибку кодирования.

+0

Работа. Благодаря! –

Смежные вопросы