##language:zh #pragma section-numbers on ''' cURL lib py 实现 ''' ::-- ZoomQuiet [<>] <> ## 默许导航,请保留 <> = PycURL = pycurl — A Python interface to the cURL library Pycurl包是一个libcurl的Python接口.pycurl已经成功的在Python2.2到Python2.5版编译测试过了. Libcurl 是一个支持FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 和 LDAP的客户端URL传输库.libcurl也支持HTTPS认证,HTTP POST,HTTP PUT,FTP上传,代理,Cookies,基本身份验证,FTP文件断点继传,HTTP代理通道等等. Libcurl提供的所有功能都可以通过pycurl接口来使用.接下来的子章节概述怎么使用pycurl接口,并且假定已经知道了libcurl如何工作的.libcurl如何工作的更多信息,请参考curl库的web页面(http://curl.haxx.se/libcurl/c/). Module Functionality pycurl.global_init(option) ->None 选项是以下常量之一:pycurl.GLOBAL_SSL, pycurl.GLOBAL_WIN32, pycurl.GLOBAL_ALL, pycurl.GLOBAL_NOTHING, pycurl.GLOBAL_DEFAULT. 相应的是libcurl的 curl_global_init() 方法. pycurl.global_cleanup() -> None 相应的是libcurl的curl_global_cleanup()方法. pycurl.version 这是liburl当前版本的信息,相应的是liburl的curl_version()方法. 用法举例: {{{ #!python >>> import pycurl >>> pycurl.version 'libcurl/7.12.3 OpenSSL/0.9.7e zlib/1.2.2.1 libidn/0.5.12' }}} pycurl.version_info() -> Tuple 相对应的是libcurl中的 curl_version_info() 方法. 返回一个序列信息就像liburl的curl_version_info()方法返回的 curl_version_info_data 结构化数据. 用法举例: {{{ #!python >>> import pycurl >>> pycurl.version_info() (2, '7.12.3', 461827, 'i586-pc-linux-gnu', 1565, 'OpenSSL/0.9.7e', 9465951, '1.2.2.1', ('ftp', 'gopher', 'telnet', 'dict', 'ldap', 'http', 'file', 'https', 'ftps'), None, 0, '0.5.12') }}} pycurl.Curl() -> Curl object 这个函数创建一个同libcurl中的CURL处理器相对应的Curl对象.Curl对象自动的设置CURLOPT_VERBOSE为0, CURLOPT_NOPROGRESS为1,提供一个默认的CURLOPT_USERAGENT和设置CURLOPT_ERRORBUFFER指向一个私有的错误缓冲区. pycurl.CurlMulti() -> CurlMulti object 这个函数创建一个新的与libcurl中的CURLM处理器相对应的CurlMulti对象. pycurl.CurlShare() -> CurlShare object 这个函数创建一个新的与libcurl中的CURLSH处理器相对应的CurlShare对象.CurlShare对象可以在Curl对象上传递SHARE选项参数. [待续] PS:本文翻译自PycURL的官方网站:http://pycurl.sourceforge.net/doc/pycurl.html,如有转贴请注明ChumpKlutz原创翻译 Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2146079 Subsections # Curl objects # CurlMulti objects # CurlShare objects # Callbacks Curl Object Curl对象具有以下方法: '''close() -> None''' 对应的是libcurl中的curl_easy_cleanup方法.当Curl对象不再被引用时pycurl会自动调用这个方法,但也可直接地调用这个方法. '''perform() -> None''' 对应于libcurl中的curl_easy_perform方法. '''setopt(option, value) -> None''' 对应于libcurl中的curl_easy_setopt方法, option使用libcurl中的CURLOPT_*常量来指定,只可惜CURLOPT_前缀现在已经被去掉了.value的数据类型依赖于 option,它可以是一个字符串,整型,长整型,文件对象,列表或是函数. 用法举例: {{{ #!python import pycurl c = pycurl.Curl() c.setopt(pycurl.URL, "http://www.python.org/") c.setopt(pycurl.HTTPHEADER, ["Accept:"]) import StringIO b = StringIO.StringIO() c.setopt(pycurl.WRITEFUNCTION, b.write) c.setopt(pycurl.FOLLOWLOCATION, 1) c.setopt(pycurl.MAXREDIRS, 5) c.perform() print b.getvalue() }}} '''getinfo(option) -> Result''' 对应于libcurl中的curl_easy_getinfo方法, option同样使用libcurl中的CURLOPT_*常量来指定,只可惜CURLOPT_前缀现在已经被去掉了. Result包含一个整数,浮点数或字符串,这都信赖于给定的option.getinfo方法不能在perform方法未调用或完成之前进行调用. 用法举例: '''errstr() -> String''' 返回这个处理器中内部libcurl错误缓冲区的字符串表示. CurlMulti Object CurlMulti对象具有以下方法: close() -> None 对应于libcurl中的curl_multi_cleanup()方法.当CurlMulti对象不再被引用时pycurl会自动调用该方法,也可显示调用该方法. perform() -> tuple of status and the number of active Curl objects 对应于libcurl中的curl_multi_perform()方法. add_handle(Curl object) -> None 对应于libcurl中的curl_multi_add_handle()方法.这个方法添加一个有效的Curl对象到CurlMulti对象. 重要提示:add_handle没有隐式的增加对Curl对象的引用(因而也没有增加Curl对象的引用次数) remove_handle(Curl object) -> None 对应于libcurl中的curl_multi_remove_handle()方法.这个方法从CurlMulti对象中移除一个现有的Curl对象. 重要提示:remove_handle不会隐式的移除Curl对象的引用(因而不会减少Curl对象的引用次数). fdset() -> triple of lists with active file descriptors, readable, writeable, exceptions. 对应于libcurl中的curl_multi_fdset()方法.这个方法从CurlMulti对象中提取文件描述信息.返回的列表可以被用于select模块to poll for events. 用法举例: {{{ #!python import pycurl c = pycurl.Curl() c.setopt(pycurl.URL, "http://curl.haxx.se") m = pycurl.CurlMulti() m.add_handle(c) while 1: ret, num_handles = m.perform() if ret != pycurl.E_CALL_MULTI_PERFORM: break while num_handles: apply(select.select, m.fdset() + (1,)) while 1: ret, num_handles = m.perform() if ret != pycurl.E_CALL_MULTI_PERFORM: break }}} '''select(timeout) -> number of ready file descriptors or -1 on timeout''' 这是一个有用的函数,它简化了fdest()和select模块的组合使用. 用法举例: {{{ #!python import pycurl c = pycurl.Curl() c.setopt(pycurl.URL, "http://curl.haxx.se") m = pycurl.CurlMulti() m.add_handle(c) while 1: ret, num_handles = m.perform() if ret != pycurl.E_CALL_MULTI_PERFORM: break while num_handles: ret = m.select(1.0) if ret == -1: continue while 1: ret, num_handles = m.perform() if ret != pycurl.E_CALL_MULTI_PERFORM: break }}} info_read([max]) -> numberof queued messages, a list of successful objects, a list of failed objects 对应于libcurl中的curl_multi_info_read()方法.这个方法从多重栈中提取至多max个信息然后返回两个列表.第一个列表包含成功完成的操作第二个列表包含每一个失败的curl对象的序列. [待续] PS:本文翻译自PycURL的官方网站:http://pycurl.sourceforge.net/doc/pycurl.html,如有转贴请注明ChumpKlutz原创翻译 Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2146140 CurlShare Object CurlShare对象具有以下方法: setopt(option, value) -> None 对应于libcurl中的curl_share_setopt方法, option使用libcurl中的CURLOPT_*常量来指定,只可惜CURLOPT_前缀现在改成SH_了.通常value必须是 LOCK_DATA_COOKIE 或者说LOCK_DATA_DNS. 用法举例: {{{ #!python import pycurl curl = pycurl.Curl() s = pycurl.CurlShare() s.setopt(pycurl.SH_SHARE, pycurl.LOCK_DATA_COOKIE) s.setopt(pycurl.SH_SHARE, pycurl.LOCK_DATA_DNS) curl.setopt(pycurl.URL, 'http://curl.haxx.se') curl.setopt(pycurl.SHARE, s) curl.perform() curl.close() }}} Callbacks 为了更好的控制,libcurl允许把一些回调函数关联到每个连接中.在pycurl中,回调函数通过Curl对象调用setopt为s WRITEFUNCTION, READFUNCTION, HEADERFUNCTION, PROGRESSFUNCTION, IOCTLFUNCTION, 或DEBUGFUNCTION这些选项设置.这些选项对应着libcurl中CURLOPT_*前缀被移除的选项.在pycurl中回调函数必须是一个正规的Python函数,或者一个类的方法或是一个扩展的函数类型. 这儿有些局限性就是这些选项的回调函数有可能同时发生.它允许不同的回调函数对应到不同的Curl对象.更多明确的是,WRITEDATA的回调函数不能用于WRITEFUNCTION,READDATA的回调函数不能用于 READFUNCTION,WRITEHEADER的回调函数不能用于HEADERFUNCTION,PROGRESSDATA回调函数不能用于 PROGRESSFUNCTION,IOCTLDATA回调函数不能用于IOCTLFUNCTION,DEBUGDATA回调函数不能用于 DEBUGFUNCTION.实际上,可以通过把一个类的实例方法来当作回调函数并且使用类实例属性像文件对象那样存储每个对象的数据来克服这种局限性. Pycurl中的每个回调函数的签名如下: {{{ WRITEFUNCTION(string) -> number of characters written READFUNCTION(number of characters to read)-> string HEADERFUNCTION(string) -> number of characters written PROGRESSFUNCTION(download total, downloaded, upload total, uploaded) -> status DEBUGFUNCTION(debug message type, debug message string) -> None }}} IOCTLFUNCTION(ioctl cmd) -> status Example: Callbacks for document header and body 这个例子打印头数据到stderr打印内容数据到stdout.同样注意它们都不返回写入的字节数. WRITEFUNCTION和HEADERFUNCTION回调,写入所有字节时返回None. {{{ #!python ## Callback function invoked when body data is ready def body(buf): # Print body data to stdout import sys sys.stdout.write(buf) # Returning None implies that all bytes were written ## Callback function invoked when header data is ready def header(buf): # Print header data to stderr import sys sys.stderr.write(buf) # Returning None implies that all bytes were written c = pycurl.Curl() c.setopt(pycurl.URL, "http://www.python.org/") c.setopt(pycurl.WRITEFUNCTION, body) c.setopt(pycurl.HEADERFUNCTION, header) c.perform() }}} Example: Download/upload progress callback 这个例子演示如何使用进度回调.当下载一个文档时,uploads参数都将是0,反之亦然. {{{#!python ## Callback function invoked when download/upload has progress def progress(download_t, download_d, upload_t, upload_d): print "Total to download", download_t print "Total downloaded", download_d print "Total to upload", upload_t print "Total uploaded", upload_d c.setopt(c.URL, "http://slashdot.org/") c.setopt(c.NOPROGRESS, 0) c.setopt(c.PROGRESSFUNCTION, progress) c.perform() }}} Example: Debug callbacks 这个例子演示如何使用调试回调.调试信息类型是一个调试信息的整数标示类型.在这个回调被调用时VERBOSE选项必须可用. {{{#!python def test(debug_type, debug_msg): print "debug(%d): %s" % (debug_type, debug_msg) c = pycurl.Curl() c.setopt(pycurl.URL, "http://curl.haxx.se/") c.setopt(pycurl.VERBOSE, 1) c.setopt(pycurl.DEBUGFUNCTION, test) c.perform() }}} Other examples Pycrul 也包含一些用于演示如何在libcurl中使用不同的回调的测试脚本和事例.例如,文件examples/file_upload.py包含如何使用 READFUNCTION的事例代码, 'tests/test_cb.py'演示WRITEFUNCTION和HEADERFUNCTION, 'tests/test_debug.py'演示DEBUGFUNCTION, 'tests/test_getinfo.py'演示PROGRESSFUNCTION. [全结束] PS:本文翻译自PycURL的官方网站:http://pycurl.sourceforge.net/doc/pycurl.html,如有转贴请注明ChumpKlutz原创翻译 Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2146192 = PycURL for python26/win32 = ''Compiled By andelf (andelf@gmail.com)'' 官方已经停在了 7.19.0 版本. 而且貌似很难编译. 这里提供 for python26 的 pycurl, 改了下版本号, 和 curl 相同, 为 10.4.22 最新软件包(所有). * OpenSSL 1.0.0 * libcurl 7.20.1 * zlib 1.2.5 * c-ares 1.7.1 * libssh2 1.2.5 静态编译版. 动态的 dll 太恐怖了. {{{ pycurl.version 'libcurl/7.20.1 OpenSSL/1.0.0 zlib/1.2.5 c-ares/1.7.1 libssh2/1.2.5' }}} 下载 zip: [[attachment:pycurl-7.20.1-bin-win32-py26.zip]] exe 安装文件: [[attachment:pycurl-7.20.1.win32-py2.6.zip]] = 下载 = for win32, win64 http://www.lfd.uci.edu/~gohlke/pythonlibs/ = 反馈 = <>