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()
运行结果: