Python2.5使用新浪微博Python SDK遇到的问题与解决方法
2010-10-26 04:08 onm 阅读(247) 评论(0) 编辑 收藏 举报上周花了一周时间做了一个GAE(Google App Engine)的与新浪微博交互的网络应用——爱颜色。期间遇到了一些问题,经过一番搜索和思考将它们解决。现在分享给大家,也希望对于不妥的地方得到大家的指正。
首先是OAuth验证问题,这事我折腾了很久才弄明白怎么回事,本想自己写一篇总结了,后来想想还是算了,在网上找到了很多很好用但是比较稀缺的资源,如下:
先来一个官方网站:http://oauth.net/
然后是新浪微博官方网站上的:http://open.t.sina.com.cn/wiki/index.php/Oauth_new
广为流传的:http://blog.csdn.net/hereweare2009/archive/2009/03/08/3968582.aspx
说的比较形象的:http://www.skiyo.cn/2010/08/11/understanding-oauth-and-douban-oauth-test/(虽然这个是说豆瓣的,但是原理是一样的)
然后是我找到的唯一一个和Python有关的,使用Python的SDK的一个OAuth验证的Web应用的详细代码(SDK默认提供的是桌面应用验证的代码,要输入PIN值,网络应用不是很方便)(非常感谢这位作者):http://www.cnblogs.com/fengmk2/archive/2010/09/27/sina-weibo-oauth-on-django.html
有了上面那些,应该就不愁新浪微博的OAuth验证了。
然后开始实战,刚动手就遇到问题了,新浪微博Python 2.x的SDK貌似和Python2.5不兼容,这里是下载地址。(我没用过别的版本的Python,所以希望用过高版本的2.X系列的朋友告诉一生是否可以直接使用。)
我用的SDK是20100906版本的。因为api.py这个文件中的197行(就是下面的最后一行)有问题,运行会直接报错。附近代码如下:
191 192 193 194 195 196 197 | return bind_api( path = '/statuses/upload.json' , method = 'POST' , payload_type = 'status' , require_auth = True , allowed_param = allowed_param )( self , * args, post_data = post_data, headers = headers) |
后来,我曾尝试上传到GAE的真实环境上,也会报错。说明新浪微博的PythonSDK在Python2.5下是有问题的。最初的解决方法是——暴力法……我直接将这一行后面的(self, *args, post_data=post_data, headers=headers)给注释掉了。所幸在前期开发一切安好。
但到后来我需要调用upload这个方法进行上传图片微博时,遇到了问题。(我上网找了很久,由于这方面信息太少了,基本搜不到用Python SDK开发新浪微博应用的资料,一般像这种东西外国人写的资料会比较多,但无奈新浪微博是中国的应用,所以外国网站是绝不会搜到的……)
然后我通过了很多方法尝试,最主要的是我将之前把这行代码注掉的事情给忘了……
我只能不断的跟踪源码中的关于生成这个post请求的中,生成的header和MIME的信息的部分,希望从中找到答案。新浪微博API文档中关于upload这个方法的描述中的最后部分,有一个测试方法,可以相关工具观看上传图片时,HTTP传送数据的信息。
我试着对比了几次这个信息和API中生成的header和MIME信息中的差别,跟踪了N次也不得其解。后来才想起来我曾注掉的那行代码,然后将它做了如下修改。(后来根据进一步跟进调试得知,由于注释掉了那段代码,所以我的数据其实没有传进去,也就没有post给新浪微博API的服务器。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | """ statuses/upload """ def upload( self , filename, status, lat = None , long = None , source = None ): if source is None : source = self .source headers, post_data = API._pack_image(filename, 1024 , source = source, status = status, lat = lat, long = long , contentname = "pic" ) args = [status] allowed_param = [ 'status' ] if lat is not None : args.append(lat) allowed_param.append( 'lat' ) if long is not None : args.append( long ) allowed_param.append( 'long' ) if source is not None : args.append(source) allowed_param.append( 'source' ) kargs = { 'post_data' : post_data, 'headers' : headers, } return bind_api( path = '/statuses/upload.json' , method = 'POST' , payload_type = 'status' , require_auth = True , allowed_param = allowed_param )( self , * args, * * kargs) |
然后就可以用了。这样post_data和headers的信息才绑定给了api,将数据post给新浪微博API相关的地址。
爱颜色还有一个需求,就是上传文件时不是打开本地的一个文件然后上传。然而新浪微博Python的SDK里只有打开文件上传的方法,而我需要的是动态生成一个颜色的图像的二进制数据,并将图像的二进制数据直接上传到微博API的服务器。
我本不想在SDK的内部动手脚,但没有找到更好的办法。后来在内部加了一个新的upload方法,这里涉及到图像处理的一个内部函数API._pack_image_data,这个方法负责包装post请求的header和MIME信息,重点是包装了图像的二进制信息,它是根据文件名打开文件,然后读取二进制数据再将其以“Content-Transfer-Encoding: binary”方式post给新浪微博api的服务器。
我在这里将打开文件读取二进制数据,然后修改了API._pack_image_data(修改了部分细节,如判断文件大小,判断文件类型的部分,见代码中高亮的部分。),改为直接将图像二进制数据传给API._pack_image_data方法参数的方式,然后API._pack_image_data方法直接处理传进去的二进制数据。具体方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | @staticmethod def _pack_image_data(file_type, data, imagename, max_size = 1024 , source = None , status = None , lat = None , long = None , contentname = "pic" ): """Pack image from file into multipart-formdata post body""" # image must be less than 700kb in size try : if len (data) > (max_size * 1024 ): raise WeibopError( 'File is too big, must be less than 700kb.' ) #except os.error, e: except os.error: raise WeibopError( 'Unable to access file' ) # image must be gif, jpeg, or png if file_type is None : raise WeibopError( 'Could not determine file type' ) if file_type not in [ 'image/gif' , 'image/jpeg' , 'image/png' ]: raise WeibopError( 'Invalid file type for image: %s' % file_type) # build the mulitpart-formdata body BOUNDARY = 'Tw3ePy' body = [] if status is not None : body.append( '--' + BOUNDARY) body.append( 'Content-Disposition: form-data; name="status"' ) body.append( 'Content-Type: text/plain; charset=US-ASCII' ) body.append( 'Content-Transfer-Encoding: 8bit' ) body.append('') body.append(status) if source is not None : body.append( '--' + BOUNDARY) body.append( 'Content-Disposition: form-data; name="source"' ) body.append( 'Content-Type: text/plain; charset=US-ASCII' ) body.append( 'Content-Transfer-Encoding: 8bit' ) body.append('') body.append(source) if lat is not None : body.append( '--' + BOUNDARY) body.append( 'Content-Disposition: form-data; name="lat"' ) body.append( 'Content-Type: text/plain; charset=US-ASCII' ) body.append( 'Content-Transfer-Encoding: 8bit' ) body.append('') body.append(lat) if long is not None : body.append( '--' + BOUNDARY) body.append( 'Content-Disposition: form-data; name="long"' ) body.append( 'Content-Type: text/plain; charset=US-ASCII' ) body.append( 'Content-Transfer-Encoding: 8bit' ) body.append('') body.append( long ) body.append( '--' + BOUNDARY) body.append( 'Content-Disposition: form-data; name="' + contentname + '"; filename="%s"' % imagename) body.append( 'Content-Type: %s' % file_type) body.append( 'Content-Transfer-Encoding: binary' ) body.append('') body.append(data) body.append( '--' + BOUNDARY + '--' ) body.append('') body.append( '--' + BOUNDARY + '--' ) body.append('') body = '\r\n' .join(body) # build headers headers = { 'Content-Type' : 'multipart/form-data; boundary=Tw3ePy' , 'Content-Length' : len (body) } return headers, body |
至于动态生成图像二进制数据,我使用了pngCanvas,一个使用纯Python代码的生成png图像的工具。于是关于使用Python2.5和新浪微博SDK上传图片微博就大体折腾完了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述