我正在使用一个python库(poster),它将类似文件的对象作为参数,文档声明:
类文件对象必须支持.read()和.fileno()或两者 .seek()和.tell()。
我已经使用python open
函数尝试了该库,它工作正常。我目前正在使用以下内容从URL下载图像:
access_token = "XXXXXXXXXXXXXXXXXXXXX"
postPhotoUrl = "https://graph.facebook.com/me/photos?access_token=%s" % access_token
register_openers()
# get image from external URL
data = urllib2.urlopen("http://example.com/image.png")
data = StringIO(data.read())
### data, headers = multipart_encode({"source":open("file.png")}) <- WORKS FINE
data, headers = multipart_encode({"source":data})
request = urllib2.Request(postPhotoUrl,data,headers)
编辑:我的目标是从外部URL获取图像并使用facebook图形api进行POST。当我使用python open
函数时,我没有任何问题。当我尝试使用StringIO时,没有发送带有POST请求的正文。
答案 0 :(得分:4)
如果想要使用poster
包进行流式HTTP上传,则不应将图像数据转换为PIL Image
对象。只是做...
data = urllib2.urlopen("http://example.com/image.png")
data = StringIO(data.read())
...然后您可以将data
变量传递给poster
。
当然,除非你想先用PIL转换图像,但你可能应该在你的问题中提到它。
<强>更新强>
至于为什么它失败了StringIO
,可能是poster
正在检查打开文件的文件名,并使用它来确定正确的Content-Type
或某些,从StringIO
阅读时无法做到。
我从来没有使用过该软件包,并且示例不是很全面,但是当你调用类似的东西时,可能需要检查headers
变量之间的区别......
from poster.encode import multipart_encode
data = open('example.png', 'rb')
datagen, headers = multipart_encode({"image1": data})
...与...
from poster.encode import multipart_encode
data = urllib2.urlopen("http://example.com/image.png")
data = StringIO(data.read())
datagen, headers = multipart_encode({"image1": data})
更新#2
看起来我对Content-Type
的事情是正确的。来自poster
源代码encode.py
第168-174行......
if hasattr(value, 'read'):
# Looks like a file object
filename = getattr(value, 'name', None)
if filename is not None:
filetype = mimetypes.guess_type(filename)[0]
else:
filetype = None
...如果filename
为None
,则可能存在其他问题。试试这个......
from poster.encode import multipart_encode, MultipartParam
data = urllib2.urlopen("http://example.com/image.png")
data = StringIO(data.read())
param = MultipartParam(name='source',
filename='image.png',
filetype='image/png',
fileobj=data)
datagen, headers = multipart_encode({"source": param})