Python2.5使用新浪微博Python SDK遇到的问题与解决方法
2010-10-26 04:08
1371 查看
上周花了一周时间做了一个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值,网络应用不是很方便)(非常感谢这位作者):/article/4885303.html
有了上面那些,应该就不愁新浪微博的OAuth验证了。
然后开始实战,刚动手就遇到问题了,新浪微博Python 2.x的SDK貌似和Python2.5不兼容,这里是下载地址。(我没用过别的版本的Python,所以希望用过高版本的2.X系列的朋友告诉一生是否可以直接使用。)
我用的SDK是20100906版本的。因为api.py这个文件中的197行(就是下面的最后一行)有问题,运行会直接报错。附近代码如下:
后来,我曾尝试上传到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的服务器。)
然后就可以用了。这样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方法直接处理传进去的二进制数据。具体方法如下:
至于动态生成图像二进制数据,我使用了pngCanvas,一个使用纯Python代码的生成png图像的工具。于是关于使用Python2.5和新浪微博SDK上传图片微博就大体折腾完了。
首先是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值,网络应用不是很方便)(非常感谢这位作者):/article/4885303.html
有了上面那些,应该就不愁新浪微博的OAuth验证了。
然后开始实战,刚动手就遇到问题了,新浪微博Python 2.x的SDK貌似和Python2.5不兼容,这里是下载地址。(我没用过别的版本的Python,所以希望用过高版本的2.X系列的朋友告诉一生是否可以直接使用。)
我用的SDK是20100906版本的。因为api.py这个文件中的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的服务器。)
""" 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方法直接处理传进去的二进制数据。具体方法如下:
@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上传图片微博就大体折腾完了。
相关文章推荐
- windows下安装python basemap时使用Visual Studio编译geos时遇到的问题以及解决方法
- 记录使用python时遇到的中文 编码问题与解决方法
- linux Eclipse上c++调用使用了tensorflow库的python程序遇到的问题及解决方法
- Windows下使用python-nmap库可能遇到的问题及解决方法(续)
- Windows下使用python-nmap库可能遇到的问题及解决方法(续)
- 使用Python脚本实现批量网站存活检测遇到问题及解决方法
- Python结巴中文分词工具使用过程中遇到的问题及解决方法
- python在linux下使用多进程遇到3770问题解决方法
- 使用 Android Studio 跑新浪微博SDK Demo遇到的问题及解决
- 使用Python脚本实现批量网站存活检测遇到问题及解决方法
- J2ME使用WTK模拟器开发时候遇到“OK to use Airtime” 问题的解决方法
- 解决Python使用pip安装时遇到的解码错误问题
- 用python编写ASP脚本时遇到的问题,初步的解决方法,目前正在寻找更好的解决办法。
- 使用adb shell时遇到的问题及解决方法
- 使用ArcGIS GP服务遇到的问题,原因以及解决方法 - 客户端API开发(Javascript/Flex/Silverlig 转载
- 使用Adobe PDF Reader组件遇到问题之解决方法
- [完]Python 安装setuptools,解决使用Matplotlib遇到的问题
- Java使用Oracle遇到的最大游标超出问题及其解决方法
- python中cx_Oracle模块安装遇到的问题与解决方法
- 升级Struts2.5后使用DMI动态方法调用遇到问题