1、 pycurl 库是功能强大的python的url库,是用c语言写的,速度很快,比urllib和httplib都快。支持操作协议有FTP, HTTP,HTTPS,TELNET等,通过pycurl提供的方法,可以实现探测WEB服务质量的情况,比如,响应的HTTP状态码、请求延时、HTTP头信息、下载速度等。

2 、pycurl官方网站: pycurl 官方

3、 pycurl libcurl 的Python 接口。 pycurl 可用于从 Python 程序中获取由 URL 标识的对象,类似于 urllib Python 模块。 pycurl 模块 成熟,速度非常快,并且支持很多特性。

4、 libcurl 是一个免费且易于使用的客户端 URL 传输库 ,支持 FTP、FTPS、HTTP、HTTPS、SCP、SFTP、TFTP、TELNET、DICT、LDAP、LDAPS、FILE、IMAP、SMTP、POP3 和 RTSP。 libcurl 支持 SSL 证书、HTTP POST、HTTP PUT、FTP 上传、基于 HTTP 表单的上传、代理、cookie、用户+密码身份验证(Basic、Digest、NTLM、Negotiate、Kerberos4)、文件传输恢复、http 代理隧道等等。

5、 libcurl 库是高度可移植的,它可以在多种平台上构建和工作,包括 Solaris、NetBSD、FreeBSD、OpenBSD、Darwin、HPUX、IRIX、AIX、Tru64、Linux、UnixWare、HURD、Windows、Amiga、OS/2、BeOs、Mac OS X、Ultrix、QNX、OpenVMS、RISC OS、Novell NetWare、DOS 等...

6、 libcurl 是免费的、线程安全的、与 IPv6 兼容、功能丰富、支持良好、速度快、文档完整 ,并且已被许多知名、成功的大公司和众多应用程序使用。

7、 pycurl 库的主要缺点是它是 libcurl 之上的一个相对薄的层,没有任何那些漂亮的 Pythonic 类层次结构。

1、第一种方式(pip安装方式):

[root@localhost ~]$ pip install pycurl

2、第二种方式(下载源码安装方式):

yum install libcurl-devel
wget https://curl.haxx.se/download/curl-7.61.0.tar.gz
tar -zxvf curl-7.61.0.tar.gz
cd curl-7.61.0/
./configure 
make && make install
export LD_LIBRARY_PATH=/usr/local/lib

3、测试 pycurl 库是否安装成功,命令行执行如下代码:

import pycurl
print(pycurl.version)

1、 close() 方法:对应libcurl包中的curl_easy_cleanup方法,无参数,实现关闭,回收Curl对象。

2、 perform() 方法:对应libcurl包中的curl_easy_perform方法,无参数,实现Curl对象请求的提交。

3、 setopt(option, value) 方法:对应libcurl包中的curl_easy_setopt方法,参数option是通过libcurl的常量来指定的,参数value的值会依赖option,可以是一个字符串、整型,长整型,文件对象,列表或函数等。

c = pycurl.Curl()  # 创建一个curl对象
c.setopt(pycurl.CONNECTTIMEOUT, 5)  # 连接的等待时间,设置为0则不等待
c.setopt(pycurl.TIMEOUT, 5)  # 请求超时时间
c.setopt(pycurl.NOPROGRESS, 0)  # 是否屏蔽下载进度条,非0则屏蔽
c.setopt(pycurl.MAXREDIRS, 5)  # 指定HTTP重定向的最大数
c.setopt(pycurl.FORBID_REUSE, 1)  # 完成交互后强制断开连接,不重用
c.setopt(pycurl.FRESH_CONNECT, 1)  # 强制获取新的连接,即替代缓存中的连接
c.setopt(pycurl.DNS_CACHE_TIMEOUT, 60)  # 设置保存DNS信息的时间,默认为120秒
c.setopt(pycurl.URL, "http://www.baidu.com")  # 指定请求的URL
c.setopt(pycurl.USERAGENT, "Mozilla/5.2 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50324)")  # 配置请求HTTP头的User-Agent
c.setopt(pycurl.HEADERFUNCTION, getheader)  # 将返回的HTTP HEADER定向到回调函数getheader
c.setopt(pycurl.WRITEFUNCTION, getbody)  # 将返回的内容定向到回调函数getbody
c.setopt(pycurl.WRITEHEADER, fileobj)  # 将返回的HTTP HEADER定向到fileobj文件对象
c.setopt(pycurl.WRITEDATA, fileobj)  # 将返回的HTML内容定向到fileobj文件对象
c.setopt(pycurl.VERBOSE, 1) # 是否在控制台上显示请求URL的请求头和响应头信息

4、 getinfo(option) 方法:对应libcurl包中的curl_easy_getinfo方法,参数option是通过libcurl的常量来指定的。

c = pycurl.Curl()  # 创建一个curl对象
c.getinfo(pycurl.HTTP_CODE)  # 返回的HTTP状态码
c.getinfo(pycurl.TOTAL_TIME)  # 传输结束所消耗的总时间
c.getinfo(pycurl.NAMELOOKUP_TIME)  # DNS解析所消耗的时间
c.getinfo(pycurl.CONNECT_TIME)  # 建立连接所消耗的时间
c.getinfo(pycurl.PRETRANSFER_TIME)  # 从建立连接到准备传输所消耗的时间
c.getinfo(pycurl.STARTTRANSFER_TIME)  # 从建立连接到传输开始消耗的时间
c.getinfo(pycurl.REDIRECT_TIME)  # 重定向所消耗的时间
c.getinfo(pycurl.SIZE_UPLOAD)  # 上传数据包大小
c.getinfo(pycurl.SIZE_DOWNLOAD)  # 下载数据包大小
c.getinfo(pycurl.SPEED_DOWNLOAD)  # 平均下载速度
c.getinfo(pycurl.SPEED_UPLOAD)  # 平均上传速度
c.getinfo(pycurl.HEADER_SIZE)  # HTTP头部大小

1、探索web服务质量

HTTP服务是最流行的互联网应用之一,服务质量的好坏关系到用户体验以及网站的运营服务水平,最常用的有两个标准:

  • 一为服务的可用性,比如是否处于正常提供服务状态,而不是出现404页面或500页面错误等;
  • 二是服务响应的速度,比如静态类文件下载时间都控制在毫秒级,动态CGI为秒级。
  • 本实例使用 pycurl 模块的 setopt getinfo 方法实现对HTTP服务质量的探测,获取监控URL返回的HTTP状态码,HTTP状态码采用 pycurl.HTTP_CODE 常量,以及从HTTP请求到下载期间各环节的响应时间,通过 pycurl.NAMELOOKUP_TIME pycurl.CONNECT_TIME pycurl.PRETRANSFER_TIME pycurl.R 等常量来时间。另外通过 pycurl.WRITEHEADER pycurl.WRITEDATA 常量得到目标URL的HTTP响应头部及页面内容。

    第一种方法:

    #!/usr/bin/python
    # -*- coding:UTF-8 -*-
    import os
    import sys
    import pycurl
    # 探测的目标URL
    URL = "http://www.baidu.com"
    # 创建一个Curl对象
    c = pycurl.Curl()
    # 定义请求的URL常量
    c.setopt(pycurl.URL, URL)
    # 定义请求连接的等待时间
    c.setopt(pycurl.CONNECTTIMEOUT, 5)
    # 定义请求超时时间
    c.setopt(pycurl.TIMEOUT, 5)
    # 屏蔽下载进度条
    c.setopt(pycurl.NOPROGRESS, 1)
    # 完成交互后强制断开连接,不重用
    c.setopt(pycurl.FORBID_REUSE, 1)
    # 指定HTTP重定向的最大数为1
    c.setopt(pycurl.MAXREDIRS, 1)
    # 设置保存DNS信息的时间为30秒
    c.setopt(pycurl.DNS_CACHE_TIMEOUT, 30)
    # 创建一个文件对象,以“wb”方式打开,用来存储返回的http头部及页面内容
    indexfile = open(os.path.dirname(os.path.realpath(__file__)) + "/content.txt", "wb")
    # 将返回的HTTP HEADER定向到indexfile文件
    c.setopt(pycurl.WRITEHEADER, indexfile)
    # 将返回的HTML内容定向到indexfile文件对象
    c.setopt(pycurl.WRITEDATA, indexfile)
    try:
        # 提交请求
        c.perform()
    except Exception as e:
        print("connection error: " + str(e))
        indexfile.close()
        c.close()
        sys.exit()
    # 获取DNS解析时间
    NAMELOOKUP_TIME = c.getinfo(c.NAMELOOKUP_TIME)
    # 获取建立连接时间
    CONNECT_TIME = c.getinfo(c.CONNECT_TIME)
    # 获取从建立连接到准备传输所消耗的时间
    PRETRANSFER_TIME = c.getinfo(c.PRETRANSFER_TIME)
    # 获取从建立连接到传输开始消耗的时间
    STARTTRANSFER_TIME = c.getinfo(c.STARTTRANSFER_TIME)
    # 获取传输的总时间
    TOTAL_TIME = c.getinfo(c.TOTAL_TIME)
    # 获取HTTP状态码
    HTTP_CODE = c.getinfo(c.HTTP_CODE)
    # 获取下载数据包大小
    SIZE_DOWNLOAD = c.getinfo(c.SIZE_DOWNLOAD)
    # 获取HTTP头部大小
    HEADER_SIZE = c.getinfo(c.HEADER_SIZE)
    # 获取平均下载速度
    SPEED_DOWNLOAD = c.getinfo(c.SPEED_DOWNLOAD)
    # 打印输出相关数据
    print("HTTP状态码: %d" % (HTTP_CODE))
    print("DNS解析时间: %.2f ms" % (NAMELOOKUP_TIME * 1000))
    print("建立连接时间: %.2f ms" % (CONNECT_TIME * 1000))
    print("准备传输时间: %.2f ms" % (PRETRANSFER_TIME * 1000))
    print("传输开始时间: %.2f ms" % (STARTTRANSFER_TIME * 1000))
    print("传输结束总时间: %.2f ms" % (TOTAL_TIME * 1000))
    print("下载数据包大小: %d bytes/s" % (SIZE_DOWNLOAD))
    print("HTTP头部大小: %d byte" % (HEADER_SIZE))
    print("平均下载速度: %d bytes/s" % (SPEED_DOWNLOAD))
    # 关闭文件及Curl对象 indexfile.close() c.close()

    运行结果:

    content.txt文件内容(存储请求URL返回的http响应头部及页面内容)

    第二种方法:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import os
    import sys
    import pycurl
    from past.builtins import raw_input
    def get_info(url):
        :param url:用户输入需要检测的URL地址
        info 字典主要用于映射dic字典
        dic字典主要存下curl结果
        :return:没return,直接print,函数可以改写,可以用于定时检测多个域名,增加一个需要检测的url列表即可
        c = pycurl.Curl()
        c.setopt(pycurl.URL, url)  # 定义请求的URL常量
        c.setopt(pycurl.CONNECTTIMEOUT, 5)  # 请求等待时间最多5秒
        c.setopt(pycurl.TIMEOUT, 5)  # 定义请求超时时间(服务器没回应)
        c.setopt(pycurl.NOPROGRESS, 1)  # 屏蔽下载进度条
        c.setopt(pycurl.FORBID_REUSE, 1)  # 交互完成后强制断开连接,不重用
        c.setopt(pycurl.MAXREDIRS, 1)  # 指定HTTP重定向的最大数为1
        c.setopt(pycurl.DNS_CACHE_TIMEOUT, 30)  # 设置DNS信息保存时间为30秒
        c.setopt(pycurl.USERAGENT,
                 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36 OPR/40.0.2308.81 (Edition Baidu)")
        dic = {}
        info = {
            'NAMELOOKUP_TIME': 'DNS解析时间',
            'CONNECT_TIME': '建立连接时间',
            'PRETRANSFER_TIME': '建立到准备传输所消耗的时间',
            'STARTTRANSFER_TIME': '建立连接到传输开始消耗的时间',
            'TOTAL_TIME': '传输总时间',
            'HTTP_CODE': 'HTTP状态码',
            'SIZE_DOWNLOAD': '下载数据包大小',
            'HEADER_SIZE': 'HTTP头部大小',
            'SPEED_DOWNLOAD': '平均下载速度'
        with open(os.path.dirname(os.path.realpath(__file__)) + "/content.txt", "wb") as index_file:
            c.setopt(pycurl.WRITEHEADER, index_file)  # 将返回的HTTP HEADER定向到index_file文件对象
            c.setopt(pycurl.WRITEDATA, index_file)  # 将返回的HTML内容定向到index_file文件对象
            try:
                c.perform()
            except Exception as e:
                print("Connection error:" + str(e))
                c.close()
                sys.exit()
            dic['NAMELOOKUP_TIME'] = '%.2f ms' % (c.getinfo(c.NAMELOOKUP_TIME) * 1000)  # 获取DNS解析时间
            dic['CONNECT_TIME'] = '%.2f ms' % (c.getinfo(c.CONNECT_TIME) * 1000)  # 获取建立连接时间
            dic['PRETRANSFER_TIME'] = '%.2f ms' % (c.getinfo(c.PRETRANSFER_TIME) * 1000)  # 获取从建立到准备传输所消耗的时间
            dic['STARTTRANSFER_TIME'] = '%.2f ms' % (c.getinfo(c.STARTTRANSFER_TIME) * 1000)  # 获取从建立连接到传输开始消耗的时间
            dic['TOTAL_TIME'] = '%.2f ms' % (c.getinfo(c.TOTAL_TIME) * 1000)  # 获取传输总时间
            dic['HTTP_CODE'] = c.getinfo(c.HTTP_CODE)  # 获取HTTP状态码
            dic['SIZE_DOWNLOAD'] = '%d bytes/s' % (c.getinfo(c.SIZE_DOWNLOAD))  # 获取下载数据包大小
            dic['HEADER_SIZE'] = '%d bytes/s' % (c.getinfo(c.HEADER_SIZE))  # 获取HTTP头部大小
            dic['SPEED_DOWNLOAD'] = '%d bytes/s' % (c.getinfo(c.SPEED_DOWNLOAD))  # 获取平均下载速度
        for key in info:
            print(info[key], ':', dic[key])
    def main():
        while True:
            URL = raw_input("请输入一个URL地址(Q for exit):")
            if URL.lower() == 'q':
                sys.exit()
            else:
                get_info(URL)
    if __name__ == '__main__':
        main()

    运行结果:

    2、HTTP GET操作

    import pycurl
    PYCURL_CONNECTTIMEOUT = 30
    PYCURL_TIMEOUT = 300
    PYCURL_DOWNLOADURL = "http://www.baidu.com"
    PYCURL_DOWNLOAD_FILE = "download.file"
    fp = open(PYCURL_DOWNLOAD_FILE, 'wb+')
    def pycurl_writeFile(buffer):
        fp.write(buffer)
    def pycurl_download(url):
        # 全局初始化
        pycurl.global_init(pycurl.GLOBAL_ALL)
        # 实例化对象
        c = pycurl.Curl()
        # 参数设置
        c.setopt(pycurl.URL, url)
        c.setopt(pycurl.WRITEDATA, fp)
        c.setopt(pycurl.WRITEFUNCTION, pycurl_writeFile)
        c.setopt(pycurl.NOPROGRESS, 0)
        c.setopt(pycurl.CONNECTTIMEOUT, PYCURL_CONNECTTIMEOUT)
        c.setopt(pycurl.TIMEOUT, PYCURL_TIMEOUT)
        c.setopt(pycurl.VERBOSE, 1)
        try:
            c.perform()
        except Exception as e:
            print(e)
        # 资源回收
        c.close()
        fp.close()
    if __name__ == '__main__':
        pycurl_download(PYCURL_DOWNLOADURL)

    运行结果:

    3、HTTP POST操作

    首先搭建一个web服务:

    再使用 pycurl 库构建请求post服务的代码:

    import pycurl
    import json
    URL = "http://127.0.0.1:5000/ProcessPOSTJSON"
    c = pycurl.Curl()
    c.setopt(pycurl.URL, URL)
    c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json'])
    data = json.dumps({"name": "xgx", "sex": "male", "country": "china"})
    print(data, type(data))
    c.setopt(pycurl.POST, 1)
    c.setopt(pycurl.POSTFIELDS, data)
    c.setopt(pycurl.VERBOSE, 1)
    c.perform()
    c.close()

    运行结果: