导入时的UnicodeDecodeError(tweepy)

1 投票
1 回答
993 浏览
提问于 2025-04-17 02:08

我正在尝试使用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是否真的在乎文件名是什么……)

撰写回答