Pycurl是Python的libcurl接口。liburl是客户端的URL传输库,它支持FTP,FTPS,HTTP,HTTPS,TELNET,LDAP等诸多协议,同时支持HTTP认证,代理,FTP上传,cookies等。


一、提取网络资源

用Pycurl来提取网络资源主要有三个步骤:

1、创造一个pycurl.Curl实例

2、使用setopt设置选项

3、调用perform来执行

import pycurl
from StringIO import StringIO

buffer=StringIO()
c=pycurl.Curl()
c.setopt(pycurl.URL,'
c.setopt(pycurl.WRITEFUNCTION,buffer.write)
c.perform()
c.close()

body=buffer.getvalue()
print body

pycurl并不能储存返回的结果,所以设置了一个缓冲区用来接收结果。官网上是用的“c.setopt(c.WRITEDATA,buffer)”,不过可能是因为版本的问题,我用Python2.7的时候这么写会报错,不知何原因。。。

如果是用Python2.X的话,输出无需转码,如果是用Python3.X,输出需要转码:print (body.decode('utf-8'))


二、检验HTTP响应的头部

c.HEADERFUNCTION:可用来获取HTTP响应的头部,并将其传给一个函数进行处理。

import pycurl
from StringIO import StringIO

def header_function(head_line):
    print head_line,
    
buffer=StringIO()
c=pycurl.Curl()
c.setopt(pycurl.URL,'http://www.baidu.com')
c.setopt(pycurl.WRITEFUNCTION, buffer.write)
c.setopt(pycurl.HEADERFUNCTION,header_function)
c.perform()
c.close()


三、写入文件

import pycurl

with open('/tmp/test', 'w') as f:
    c=pycurl.Curl()
    c.setopt(pycurl.URL, 'http://www.baidu.com')
    c.setopt(pycurl.WRITEDATA, f)
    c.perform()
    c.close()

在这里用到了WRITEDATA,可以通过。因此我猜测之前在用到StringIO时出错是因为没有指明buffer是写入模式。


四、跟踪重定向

import pycurl

c=pycurl.Curl()
c.setopt(pycurl.URL, 'http://www.python.org')
c.setopt(pycurl.FOLLOWLOCATION, True)
c.perform()
c.close()

虽然并没有调用write函数,但是默认情况下会将重定向后的网页body输出到标准输出中。


五、设置选项

Pycurl的其他一些选项:http://curl.haxx.se/libcurl/c/curl_easy_setopt.html

只要把CURLOPT_前缀去掉就是Pycurl的选项。


六、检验响应

import pycurl
from StringIO import StringIO

buffer=StringIO()
c=pycurl.Curl()
c.setopt(pycurl.URL, 'http://www.baidu.com')
c.setopt(pycurl.WRITEFUNCTION, buffer.write)
c.perform()

print 'Status: %d'%c.getinfo(pycurl.RESPONSE_CODE)
print 'Status: %d'%c.getinfo(pycurl.TOTAL_TIME)

c.close()

一些HTTP响应的信息可以通过getinfo()获得。在这里设置一个缓冲区是避免打印那些不需要的内容。一些获取信息的参数在:http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html。只要把前缀CURLINFO_去掉就行了。


七、发送表单数据

import pycurl
import urllib

c=pycurl.Curl()
c.setopt(pycurl.URL, 'http://pycurl.sourceforge.net/tests/testpostvars.php')

post_data={'field':'value'}
postfileds=urllib.urlencode(post_data)

c.setopt(pycurl.POSTFIELDS, postfileds)

c.perform()
c.close()

使用POSTFIELDS选项。。