【问题标题】:Picasa albums title encoding. Not unicode?Picasa 相册标题编码。不是统一码?
【发布时间】:2011-11-14 00:53:33
【问题描述】:

我为 Google 的 Picasa 服务编写了一个简单的客户端。我想要的是创建一个带有专辑标题名称的文件夹,并将原始照片从服务下载到该文件夹​​。 如果标题中有任何非拉丁字符,我会收到 IOError:

IOError: [Errno 2] 没有这样的文件或目录: '\xd0\x9e\xd1\x81\xd0\xb5\xd0\xbd\xd1\x8c\Autumnal-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') 解码标题,它不起作用。

【问题讨论】:

  • 解码给出什么错误?什么是标题类型(打印为 repr(photo.title.text) )
  • 它看起来已经解码了。你试过.encode('utf-8')吗?
  • @rocksportrocker repr(album.title.text) 返回str: '\xd0\x92\xd0\xb8\xd0\xb4 \xd0\xb8\xd0\xb7 \xd0\xbe\xd0\xba\xd0\xbd\xd0\xb0'
  • @d-k 是的,我试过了。结果是一样的。例如repr(album.title.text.encode('utf-8')) 返回str: '\xd0\x92\xd0\xb8\xd0\xb4 \xd0\xb8\xd0\xb7 \xd0\xbe\xd0\xba\xd0\xbd\xd0\xb0'
  • 根据code.google.com/p/picasapush/wiki/GDataPhotos,标题应该是unicode,而不是str。你有提示标题应该是什么???

标签: python gdata picasa


【解决方案1】:

你说:

@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'

【讨论】:

  • 你是对的。是西里尔文。 album_title_decoded = album.title.text.decode('utf8') destination = os.path.join(album_title_decoded, photo.title.text) 工作正常。感谢您的帮助。
  • @smirnoffs:它工作正常只是因为photo.title.text 恰好(在这种情况下)是 ASCII。为了面向未来,请按照我所说的去做:在输入时将您的文本全部转换为 Unicode。 所有路径和文件名使用Unicode
猜你喜欢
  • 2011-10-08
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-10
  • 2011-08-08
相关资源
最近更新 更多