Портал Python-программистов

Форумы сайта python.su

Вы не зашли.

Объявление

Официальная wiki коммунити: wiki.python.su обсуждение

Официальная джаббер конференция коммунити: pythonua@conference.jabber.ru (всегда 20-35 онлайн участников). Настройки

КОД ОБОРАЧИВАТЬ В ТЕГИ [code][/code]

#1 2009-10-14 16:01:28

alphaville
Питонер
Откуда: Москва
Зарегистрирован: 2009-07-17
Сообщений: 33
Профиль

В сотый раз про кодировки

Всем добрый день. Перечитал всё что поиск выдал по запросу 'unicode' но верного решения не нашёл.

Итак, в первой строчке файла прописано # -*- coding:utf-8 -*-

Программа скачивает страницу, парсит её через xpath. Страница в кодировке utf-8. Получаю таким образом строку русскоязычную и хочу её вывести.

len строки 14
type строки <type 'unicode'>
строка вообще представляет собой слово Курумоч

попытка вывести в консоль строку командой print выдаёт:

Код:

Traceback (most recent call last):
  File "ut.py", line 175, in <module>
    ut('','','','')
  File "ut.py", line 168, in ut
    ut_chain_lookup(data,x)
  File "ut.py", line 86, in ut_chain_lookup
    print n.text_content().strip()
  File "C:\Python25\lib\encodings\cp866.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-13: ch
aracter maps to <undefined>

вывод функции repr говорит что строка представляет собой:

Код:

u'\xd0\x9a\xd1\x83\xd1\x80\xd1\x83\xd0\xbc\xd0\xbe\xd1\x87'

Перепробывал различные варианты encode, decode с кодировками cp866 и utf-8.

Помогите пожалуйста!

Неактивен

 

#2 2009-10-14 16:04:59

clopomor
Забанен
Зарегистрирован: 2007-06-12
Сообщений: 154
Профиль

Re: В сотый раз про кодировки

читайте про encode/decode
коли ви отримуєте стрічку в змінну яка є юнікодною, вам необхідно декодувати з базового кодування - тобто з utf-8
при виводі вам необхідно зробити encode в кодування терміналу - cp866

Отредактированно clopomor (2009-10-14 16:07:52)

Неактивен

 

#3 2009-10-14 16:08:15

alphaville
Питонер
Откуда: Москва
Зарегистрирован: 2009-07-17
Сообщений: 33
Профиль

Re: В сотый раз про кодировки

clopomor написал:

читайте про encode/decode
коли ви отримуэте стрычку в змынну яка э юныкодною, вам необхыдно декодувати з базового кодування - тобто з utf-8
при виводі вам необхідно зробити encode в кодування термыналу - cp866

Извините, мало что понял. Я перепробывал все возможные варианты encode/decode с utf-8 и cp866.

Прошу читателей попытаться добиться различными вариациями получения из строки u'\xd0\x9a\xd1\x83\xd1\x80\xd1\x83\xd0\xbc\xd0\xbe\xd1\x87' слова Курумоч.

Неактивен

 

#4 2009-10-14 16:20:57

Daevaorn
Команда
Откуда: Москва
Зарегистрирован: 2007-02-03
Сообщений: 1368
Профиль  Вебсайт

Re: В сотый раз про кодировки

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

Неактивен

 

#5 2009-10-14 16:48:29

diam123
Питонер
Зарегистрирован: 2008-10-23
Сообщений: 78
Профиль

Re: В сотый раз про кодировки

Proshu prosheniya za translit...
Kod mojete ne pokazivat - u vas oshibka vilazit ne pri perekodirovanii iz utf-8, a pri otobrajenii v vindovoy console. Tam je napisano cp866...
Vi v fayl zapishite, i uvidite chto vse ok...
P.S. utf-8 toje bivaet razniy, naprimer v standartnoy biblioteke est takaya kodirovka kak utf_8_sig, poprobuyte esche i ee, ona chasto vstrechaetsya, u menya i u nekotorih znakomih bila podobnaya problema, chto vrode bi utf8, a vrode bi i net...

Отредактированно diam123 (2009-10-14 16:51:42)

Неактивен

 

#6 2009-10-14 16:59:26

Daevaorn
Команда
Откуда: Москва
Зарегистрирован: 2007-02-03
Сообщений: 1368
Профиль  Вебсайт

Re: В сотый раз про кодировки

diam123 написал:

Kod mojete ne pokazivat - u vas oshibka vilazit ne pri perekodirovanii iz utf-8, a pri otobrajenii v vindovoy console

Значит у вас всё-таки хороший стеклянный шар? Нет.

alphaville написал:

u'\xd0\x9a\xd1\x83\xd1\x80\xd1\x83\xd0\xbc\xd0\xbe\xd1\x87'

Это не уникодные символы внутри, а utf-8. Надо увидеть код, чтобы понять почему так вышло.

Неактивен

 

#7 2009-10-14 16:59:44

pyuser
Питонер
Откуда: г. Чита
Зарегистрирован: 2007-05-13
Сообщений: 244
Профиль

Re: В сотый раз про кодировки

'\xd0\x9a\xd1\x83\xd1\x80\xd1\x83\xd0\xbc\xd0\xbe\xd1\x87'  не похоже на юникод, поэтому символ 'u' явно лишний sad
в win-консоли без всяких ошибок выводится '\xd0\x9a\xd1\x83\xd1\x80\xd1\x83\xd0\xbc\xd0\xbe\xd1\x87'.decode("utf-8") и '\xd0\x9a\xd1\x83\xd1\x80\xd1\x83\xd0\xbc\xd0\xbe\xd1\x87'.decode("utf-8").encode("cp866") тоже отображается без ошибок

Неактивен

 

#8 2009-10-14 17:10:40

diam123
Питонер
Зарегистрирован: 2008-10-23
Сообщений: 78
Профиль

Re: В сотый раз про кодировки

Daevaorn написал:

diam123 написал:

Kod mojete ne pokazivat - u vas oshibka vilazit ne pri perekodirovanii iz utf-8, a pri otobrajenii v vindovoy console

Значит у вас всё-таки хороший стеклянный шар? Нет.

alphaville написал:

u'\xd0\x9a\xd1\x83\xd1\x80\xd1\x83\xd0\xbc\xd0\xbe\xd1\x87'

Это не уникодные символы внутри, а utf-8. Надо увидеть код, чтобы понять почему так вышло.

Inogda podrabativayu telepatom )

C:\Python25\lib\encodings\cp866.py

Ishodya iz etogo pochemu-to kajetsya chto problema imenno pri vivode v konsol`
Topikstarter (bolee chem uveren) daje ne smotrit na to, menyaesya li oshibka ili net, a pri ego operaciyah ona 100% doljna menyatsya.
Poprobovat vivesti v fayl on toje ne hochet
Poeksperimentirovat s utf_8_sig toje net (A mejdu prochim utf_8_sig eto UTF8 s signaturoy, kotoraya nahoditsya kak raz v samom nachale fayla, i skoree vsego imenno ee ne mojet otobrazit vindovaya konsol`).
Topikstarteru - nezachet za maliy ob`em informacii, to chto ne daet kod to podrazumevaet pod soboy megoprevad ego raboti =/
P.S. Takie problemi ne voznikayut u teh, kto sledit za kodirovkami...

Неактивен

 

#9 2009-10-14 17:11:26

alphaville
Питонер
Откуда: Москва
Зарегистрирован: 2009-07-17
Сообщений: 33
Профиль

Re: В сотый раз про кодировки

Привожу код:

Код:

# -*- coding:utf-8 -*-
import httplib, urllib
import lxml.html

host = 'www.yandex.ru'

headers = {'Host':host,
'User-agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'ru,en-us;q=0.7,en;q=0.3',
'Accept-Charset': 'windows-1251,utf-8;q=0.7,*;q=0.7',
'Keep-Alive': '300',
'Connection': 'keep-alive'}

conn = httplib.HTTPConnection(host)

conn.request('GET', '/',{},headers)

resp = conn.getresponse()
print resp.status

data = resp.read()

html = lxml.html.document_fromstring(data)

vakansii = html.xpath("id('foot')/table/tr/td[4]/a[3]")[0].text_content().strip()

print repr( vakansii )

Парсит главную страницу яндекса и в переменной vakansii находится слово 'Вакансии'.

Неактивен

 

#10 2009-10-14 17:29:20

diam123
Питонер
Зарегистрирован: 2008-10-23
Сообщений: 78
Профиль

Re: В сотый раз про кодировки

U mnu netu lxml sad

Неактивен

 

#11 2009-10-14 17:31:03

Daevaorn
Команда
Откуда: Москва
Зарегистрирован: 2007-02-03
Сообщений: 1368
Профиль  Вебсайт

Re: В сотый раз про кодировки

diam123 написал:

Ishodya iz etogo pochemu-to kajetsya chto problema imenno pri vivode v konsol`

Ещё раз тонко вам намекаю, что нет, проблема в другом.

alphaville написал:

Привожу код:

OMG выкидывай lxml или ищите как его вразумить! Он уже возвращает уникодные строки с закодированными символами внутри - ужас.

Способ на время побороть:

Код:

print vakansii.encode('raw-unicode-escape')

Но срочно ищите альтернативу lxml или как его заставить так не делать.

Неактивен

 

#12 2009-10-14 17:36:34

alphaville
Питонер
Откуда: Москва
Зарегистрирован: 2009-07-17
Сообщений: 33
Профиль

Re: В сотый раз про кодировки

ребята, тут то же самое без lxml:

Код:

# -*- coding:utf-8 -*-
import httplib, urllib

host = 'www.yandex.ru'

headers = {'Host':host,
'User-agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'ru,en-us;q=0.7,en;q=0.3',
'Accept-Charset': 'windows-1251,utf-8;q=0.7,*;q=0.7',
'Keep-Alive': '300',
'Connection': 'keep-alive'}

conn = httplib.HTTPConnection(host)

conn.request('GET', '/',{},headers)

resp = conn.getresponse()
print resp.status

data = resp.read()

data = data.split("""company.yandex.ru/inside/job/">""")[1]
data = data.split("</a>")[0]

print repr( data )

посмотрите пожалуйста

Отредактированно alphaville (2009-10-14 17:37:33)

Неактивен

 

#13 2009-10-14 17:40:45

Daevaorn
Команда
Откуда: Москва
Зарегистрирован: 2007-02-03
Сообщений: 1368
Профиль  Вебсайт

Re: В сотый раз про кодировки

alphaville написал:

ребята, тут то же самое без lxml:

Ну вот уже лучше - что логично. Теперь это обычная байтовая строчка в кодировке utf-8. С ней можно нормально работать.

Неактивен

 

#14 2009-10-14 17:41:08

clopomor
Забанен
Зарегистрирован: 2007-06-12
Сообщений: 154
Профиль

Re: В сотый раз про кодировки

Код:

#!/usr/bin/python
# -*- coding: utf-8 -*-

s = '\xd0\x9a\xd1\x83\xd1\x80\xd1\x83\xd0\xbc\xd0\xbe\xd1\x87'
s1 = unicode(s,"UTF-8")
print s1.encode('utf-8')

Неактивен

 

#15 2009-10-14 18:28:53

pyuser
Питонер
Откуда: г. Чита
Зарегистрирован: 2007-05-13
Сообщений: 244
Профиль

Re: В сотый раз про кодировки

Daevaorn написал:

Но срочно ищите альтернативу lxml или как его заставить так не делать.

давайте не будем трогать lxml smile очень хорошая библиотека, и по скорости и по простоте использования и
на грабли с кодировками, слава Богу, еще ни разу не наступил

хотите получить строку в определенной кодировке, так просто укажите ее smile у метода tostring есть параметр encoding

еще раз тему перечитал. возникли сомнения в плане оси, мы про виндовоз говорим?

Отредактированно pyuser (2009-10-14 18:32:20)

Неактивен

 

#16 2009-10-14 18:40:45

alphaville
Питонер
Откуда: Москва
Зарегистрирован: 2009-07-17
Сообщений: 33
Профиль

Re: В сотый раз про кодировки

pyuser написал:

Daevaorn написал:

Но срочно ищите альтернативу lxml или как его заставить так не делать.

давайте не будем трогать lxml smile очень хорошая библиотека, и по скорости и по простоте использования и
на грабли с кодировками, слава Богу, еще ни разу не наступил

хотите получить строку в определенной кодировке, так просто укажите ее smile у метода tostring есть параметр encoding

еще раз тему перечитал. возникли сомнения в плане оси, мы про виндовоз говорим?

Дак как? Я хочу с ней работать! У вас получалось парсить ей кириллицу?

Неактивен

 

#17 2009-10-14 18:42:45

Daevaorn
Команда
Откуда: Москва
Зарегистрирован: 2007-02-03
Сообщений: 1368
Профиль  Вебсайт

Re: В сотый раз про кодировки

pyuser написал:

давайте не будем трогать lxml smile

Нет позвольте, я всё-таки трону.

lxml.html неправильно обрабатывает входной поток байт, что отчетливо видно в ситуации топик-стартера. Он преобразует в уникод быйты, не декодируя кодировку.

Если на вход document_fromstring подать уже уникодную строчку, то всё будет лучше:

Код:

html = lxml.html.document_fromstring(data.decode('utf8'))

Так наверно лучше всего и поступать. Но всё-равно странное поведение.

pyuser написал:

хотите получить строку в определенной кодировке, так просто укажите ее smile у метода tostring есть параметр encoding

У HtmlElement нету tostring метода.

pyuser написал:

еще раз тему перечитал. возникли сомнения в плане оси, мы про виндовоз говорим?

alphaville написал:

File "C:\Python25\lib\encodings\cp866.py", line 12, in encode

Неактивен

 

#18 2009-10-14 18:42:55

alphaville
Питонер
Откуда: Москва
Зарегистрирован: 2009-07-17
Сообщений: 33
Профиль

Re: В сотый раз про кодировки

clopomor написал:

Код:

#!/usr/bin/python
# -*- coding: utf-8 -*-

s = '\xd0\x9a\xd1\x83\xd1\x80\xd1\x83\xd0\xbc\xd0\xbe\xd1\x87'
s1 = unicode(s,"UTF-8")
print s1.encode('utf-8')

только последняя строчка print s1.encode('cp866')

так действительно всё работает. Но это второй вариант. А в первом, где используется lxml отдаётся строка u'\xd0\x9a\xd1\x83\xd1\x80\xd1\x83\xd0\xbc\xd0\xbe\xd1\x87'.

Тоесть какая-то полная хрень. Я не хочу отказываться от lxml. Можно ли выдачу привести к нормальному виду?

Неактивен

 

#19 2009-10-14 18:45:23

alphaville
Питонер
Откуда: Москва
Зарегистрирован: 2009-07-17
Сообщений: 33
Профиль

Re: В сотый раз про кодировки

Код:

html = lxml.html.document_fromstring(data.decode('utf8'))

СПАСИБО! ОТЛИЧНЫЙ ВАРИАНТ! как мне это в голову не пришло! сутки копаюсь с этими кодировками, а не делом занимаюсь. СПАСИБО!

Неактивен

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson

Board footer

Реклама: