Господа, не пойму где затык.

Необходимо распарсить строку запроса поисковика, содержащую кириллические символы, строка берется из лога веб-сервера. Оригинальный код приводить смысла не вижу, сокращу до более короткого варианта с той же логикой.

import re
import urllib

refurl='search?hl=ru&lr=&newwindow=1&q=l4d+%D0%BA%D0%B0%D0%BA+%D0%B8%D0%B3%D1%80%D0%B0%D1%82%D1%8C+%D0%B7%D0%B0+%D0%B7%D0%BE%D0%BC%D0%B1%D0%B8+%D0%B2+%D1%81%D0%B8%D0%BD%D0%B3%D0%BB%D0%B5&start=20&sa=N' # это обрезок от строки запроса в гугле
refurl=(urllib.unquote(refurl)) # преобразую кодировку урла
# rex - это откомпиленая регулярка для выделения части урла с ключевиком
keyword=rex.split(refurl)
keyword=keyword[1].split('&') # отрезаю окончание
print(keyword[0]) # на выходе строка "l4d+как+играть+за+зомби+в+сингле", все в порядке.


А вот теперь косяк, если я попытаюсь вывести на stdout некий отформатированный вывод, например у меня он выглядит так:
print('%s %s %s %s %s' % (dict['date'], refsite, 'is engine:', se_re[i][2], keyword[0]))


то на выходе получаю:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 4: ordinal not in range(128)

Как я так понимаю он спотыкается о юникодные кириллические символы при такой попытке вывда. Как сделать корректно?

Last edited 2009-05-12 11:21:32

У меня тоже такое часто, я только не могу выразить точно, что не так - сам не понимаю :-))
Попробуйте так:
text = '%s %s %s %s %s' % (dict['date'], refsite, 'is engine:', se_re[i][2], keyword[0])
print text.encode('utf-8')


Обычно, такая ошибка возникает при записи unicode данных в файл или в консоль, где локаль не UTF. Питон пытается привести данные к байтовой строке в кодировке iso8859 или как там её и получается ошибка т.к. в такой кодировке кириллицы нету.
В консоли юникод.

Теперь спарывается на строке
text = '%s %s %s %s %s' % (dict['date'], refsite, 'is engine:', se_re[i][2], keyword[0])

с той же ошибкой.

Вообще пока интерес у меня чисто спортивный, это отладочный принт, значение keyword будет пихаться в базу и не требует вывода. Но все же напоровшись на такую проблему сильно хочется ее решить, точно еще понадобится.
Так, проблему нашел. se_re - это юникод-строка. Две юникод-строки в одном принте форматируются нормально, юникод-строка + обычная вылетают с такой ошибкой. Буду знать, никогда не сталкивался.
> У меня тоже такое часто, я только не могу выразить точно, что не так - сам не понимаю :-))

Вот тут хорошо написано:

http://stackoverflow.com/questions/368805/python-unicodedecodeerror-am-i-misunderstanding-encode#370199

http://blog.davidjanes.com/:entry:davidjanes-2004-06-09-0015/
Lab
print(keyword) # на выходе строка "l4d+как+играть+за+зомби+в+сингле", все в порядке.


Из написанного вами хорошо видно, что в keyword у вас хранится обычный string, а не unicode. Следовательно любая попытка склеить эту строку с unicode приведёт к попытке преобразования её в unicode. По умолчанию считается, что строки у нас в кодировке ASCII. Вот и вылетает у вас ошибка потому, что ASCII кодек не может раскодировать вашу строку. Рекомендую использовать следующую запись:
keyword[0] = keyword[0].decode('windows-1251') # Подставить подходящую кодировку кодировку (например 'utf-8')