在使用新浪微博的API更新一条带图片的微博时,需要使用multipart/form-data风格的POST
可以参考这篇RFC http://www.ietf.org/rfc/rfc1867.txt
需要在request头设置Content-type
Content-type = multipart/form-data; boundary=xxxx
其中 boundary=xxxx很重要,是在request的body中构造分隔符的标识
下面这是使用httpfox截取的request的body部分,即post的数据部分
--xxxx
Content-Disposition: form-data; name="status"
111
--xxxx
Content-Disposition: form-data; name="pic"; filename="shell.png"
Content-Type: image/png
图片内容
--xxxx--
在xxxx前面加上两个’-‘构成了分隔行
在xxxx前后分别加上两个’-‘就构成了结束行
另外还要注意下,换行是'\r\n',而且正式内容和说明之间还隔了一个空行
下面是使用python上传带图片的微博
def requestMultiPart(self,URI,params):
'''
params =[{'name':'pic','filename':'shell.png','type':'image/png','data':'xxx'},...]
if 'error' in return dict,thus the request was failed!
'''
if self.user_token==None or self.user_secret==None:
return False,'token or secret is None'
header = [
('oauth_consumer_key', self.APP_KEY),
('oauth_nonce', uuid.uuid4().hex),
('oauth_signature_method', 'HMAC-SHA1'),
('oauth_timestamp', int(time.time())),
('oauth_version', '1.0'),
('oauth_token',self.user_token)
]
header2 = header[:]
header2.sort()
p = 'POST&%s&%s' % (quote(URI, safe=''), quote(urlencode(header2)))
signature = hmac.new(self.APP_SECRET + '&' + self.user_secret, p, hashlib.sha1).digest().encode('base64').rstrip()
header.append(('oauth_signature', quote(signature)))
header = ', '.join(['%s="%s"' % (k, v) for (k, v) in header])
header = {'Authorization': 'OAuth realm="", %s' % header}
header['Content-type'] ='multipart/form-data; boundary=huohua'
data = ''
for param in params:
data += '--huohua\r\n'
data += 'Content-Disposition: form-data; name="%s"; '%param['name']
if 'filename' in param:
data += 'filename="%s"'%param['filename']
if 'type' in param:
data += '\r\nContent-Type: %s'%param['type']
data +='\r\n\r\n'
data += param['data']
data +='\r\n'
data += '--huohua--'
print data
try:
request = urllib2.Request(URI,data=data, headers=header)
result = urllib2.urlopen(request).read().decode('utf-8')
result = json.loads(result)
except urllib2.HTTPError,e:
result = {'error':str(e.code)+' ' + e.msg}
except:
result = {'error':'get respose from sina error: request error |'+traceback.format_exc()}
return result
def statuses_upload(self,status,imgpath):
'''
upload image and update statuses
'''
if not os.path.exists(imgpath):
return {'error':'image file not exist!'}
filename = os.path.basename(imgpath)
type = filename.split('.')[-1]
f = open(imgpath,'rb')
pic = f.read()
print len(pic)
f.close()
requst = self.sinaRequest.requestMultiPart('http://api.t.sina.com.cn/statuses/upload.json',\
[{'name':'status','data':status},{'name':'pic','filename':filename,'type':'image/'+type,'data':pic}])
return requst