导入时的UnicodeDecodeError(tweepy)
我正在尝试使用tweepy中的“update_profile_background_image”这个功能,但遇到了一个错误:
Traceback (most recent call last):
File "XXX.py", line 1401, in <module>
psn_card.gen_twitter_bg(user_db)
File "XXX.py", line 972, in gen_twitter_bg
auth_api.update_profile_background_image(file)
File "build/bdist.linux-x86_64/egg/tweepy/api.py", line 346, in update_profile_background_image
headers, post_data = API._pack_image(filename, 800)
File "build/bdist.linux-x86_64/egg/tweepy/api.py", line 729, in _pack_image
body = '\r\n'.join(body)
UnicodeDecodeError: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)
问题是:这个库在一个egg文件里,我该如何解决这个问题?这是tweepy的一个bug吗?
这个功能是用来读取一个文件(图片),然后通过POST(http)发送到Twitter的API。
错误发生在我尝试处理加载的图片时。
我的所有.py文件都设置为使用utf-8编码:
# -- coding: utf-8 --
1 个回答
4
我猜 filename
是一个Unicode字符串。可惜的是,Tweepy不支持Unicode文件名。这算不算一个bug呢?可以说是。
问题在于,它试图直接用这个Unicode字符串来创建HTTP POST数据,而不是把它转换成字节字符串:
body.append('Content-Disposition: form-data; name="image"; filename="%s"' % filename)
这样一来,body
列表中的一个字符串就变成了Unicode字符串。当你有一个字符串序列,其中有一个是Unicode字符串时,如果你尝试用 join()
把它们连接起来,结果也会是Unicode字符串。然而,HTTP POST的内容应该是字节字符串,里面包含了一些二进制数据,所以它不兼容ASCII,这就导致了隐式转换成Unicode失败。
(无论如何,Content-Disposition
中给出的文件名绝对不应该包含完整路径,就像上面的代码那样。我建议在上面的代码之前加一行,比如 filename= os.path.basename(filename).encode('us-ascii', 'ignore')
,作为一个快速的解决办法。不过我不确定Twitter是否真的在乎文件名是什么……)