Кодировка названия альбомов Picasa.Не юникод? - PullRequest
2 голосов
/ 09 сентября 2011

Я написал простой клиент для сервиса Googles Picasa. Я хочу создать папку с названием альбома и загрузить оригинальную фотографию из сервиса в эту папку. Если в заголовке есть нелатинские символы, я получил IOError:

IOError: [Errno 2] Нет такого файла или каталога: '\ Xd0 \ x9e \ xd1 \ x81 \ xd0 \ XB5 \ xd0 \ XBD \ xd1 \ x8c \ Осеннего-Equinox.jpg'

Пример кода:

import gdata.photos.service
import gdata.media
import os
import urllib2

gd_client = gdata.photos.service.PhotosService()

username = 'cha.com.ua'
albums = gd_client.GetUserFeed(user=username)
for album in albums.entry:
        photos = gd_client.GetFeed(
            '/data/feed/api/user/%s/albumid/%s?kind=photo' % (
                username, album.gphoto_id.text))

        for photo in photos.entry:
            destination = os.path.join(album.title.text, photo.title.text)
            out = open(destination, 'wb')
            out.write(urllib2.urlopen(photo.content.src).read())
            out.close()

Я попытался расшифровать заголовок с помощью .decode('utf-8'), это не работает.

1 Ответ

1 голос
/ 10 сентября 2011

Вы говорите:

@rocksportrocker repr(album.title.text) returns str:
'\xd0\x92\xd0\xb8\xd0\xb4 \xd0\xb8\xd0\xb7 \xd0\xbe\xd0\xba\xd0\xbd\xd0\xb0'

и

@d-k Yep, I've tried it. The result is the same.
For example repr(album.title.text.encode('utf-8')) returns str:
'\xd0\x92\xd0\xb8\xd0\xb4 \xd0\xb8\xd0\xb7 \xd0\xbe\xd0\xba\xd0\xbd\xd0\xb0'

Это не может быть правдой. Если первое утверждение верно, второе вызовет:

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

Похоже, что ваш str объект является строкой кириллицы в кодировке UTF-8:

>>> foo = '\xd0\x92\xd0\xb8\xd0\xb4 \xd0\xb8\xd0\xb7 \xd0\xbe\xd0\xba\xd0\xbd\xd0\xb0'
>>> from unicodedata import name
>>> for uc in foo.decode('utf8'):
...     print "U+%04X" % ord(uc), name(uc)
...
U+0412 CYRILLIC CAPITAL LETTER VE
U+0438 CYRILLIC SMALL LETTER I
U+0434 CYRILLIC SMALL LETTER DE
U+0020 SPACE
U+0438 CYRILLIC SMALL LETTER I
U+0437 CYRILLIC SMALL LETTER ZE
U+0020 SPACE
U+043E CYRILLIC SMALL LETTER O
U+043A CYRILLIC SMALL LETTER KA
U+043D CYRILLIC SMALL LETTER EN
U+0430 CYRILLIC SMALL LETTER A
>>>

Кроме того, приведенное выше совсем не похоже на текст сообщения об ошибке: '\ xd0 \ x9e \ xd1 \ x81 \ xd0 \ xb5 \ xd0 \ xbd \ xd1 \ x8c \ Autumnal-Equinox.jpg'

>>> bar =  '\xd0\x9e\xd1\x81\xd0\xb5\xd0\xbd\xd1\x8c\Autumnal-Equinox.jpg'
>>> for uc in bar.decode('utf8'):
...     print "U+%04X" % ord(uc), name(uc)
...
U+041E CYRILLIC CAPITAL LETTER O
U+0441 CYRILLIC SMALL LETTER ES
U+0435 CYRILLIC SMALL LETTER IE
U+043D CYRILLIC SMALL LETTER EN
U+044C CYRILLIC SMALL LETTER SOFT SIGN
U+005C REVERSE SOLIDUS
U+0041 LATIN CAPITAL LETTER A
U+0075 LATIN SMALL LETTER U
U+0074 LATIN SMALL LETTER T
# snipped the remainder

REVERSE SOLIDUS (обратная косая черта) указывает на то, что вы работаете в Windows. Windows просто не работает с UTF-8. Конвертировать весь ваш текст в Unicode на входе Используйте Unicode для всех путей и имен файлов. Простой пример, который работает:

>>> bar =  '\xd0\x9e\xd1\x81\xd0\xb5\xd0\xbd\xd1\x8c.txt'
>>> ubar = bar.decode('utf8')
>>> print repr(ubar)
u'\u041e\u0441\u0435\u043d\u044c.txt'
>>> f = open(ubar, 'wb')
>>> f.write('hello\n')
>>> f.close()
>>> open(ubar, 'rb').read()
'hello\n'
...