pycURL是libcurl多協議文件傳輸庫的python接口,與urllib模塊相似,PycURL可用於從python程序中獲取由URL標識的對象,功能很強大,libcurl速度很是快pycurl做爲libcurl之上的薄包裝,速度也很是快;支持多種協議SSL,身份驗證和代理選項;用於網絡操做的套接字容許將pycurl集成到應用程序的I/O循環中。html
libcurl是一個免費且易於使用的客戶端URL傳輸庫,支持DICT,FILE,FTP,FTPS,Gopher,HTTP,HTTPS,IMAP,IMAPS,LDAP,LDAPS,POP3,POP3S,RTMP,RTSP,SCP, SFTP,SMTP,SMTPS,Telnet和TFTP。libcurl支持SSL證書,HTTP POST,HTTP PUT,FTP上傳,基於HTTP表單的上傳,代理,cookies,用戶名密碼認證(Basic,Digest,NTLM,Negotiate,Kerberos4),文件傳輸恢復,http代理隧道等等。
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等等...python
libcurl是免費的,線程安全的,兼容IPv6,功能豐富, 支持良好,速度快,記錄完整,已被許多已知的大型成功公司和衆多應用程序使用。json
pycurl安裝:緩存
pycurl安裝要求:須要python版本在2.7或者3.4到更高版本;須要libcurl版本在7.19.0或更高版本。安全
在Unix上使用操做系統的包管理工具來安裝pycurl更容易,它將根據須要安裝libcurl和其餘依賴項.cookie
esay_install pycurl
pip install pycurl
源碼安裝:網絡
#要求 curl-config 包支持,須要源碼方式從新安裝 curl wget http://curl.haxx.se/download/curl-7.36.0.tar.gz tar -zxvf curl-7.36.0.tar.gz cd curl-7.36.0 ./configure make && make install export LD_LIBRARY_PATH=/usr/local/lib wget https://pypi.python.org/packages/source/p/pycurl/pycurl-7.43.0.2.tar.gz --no-check-certificate tar -zxvf pycurl-7.19.3.1.tar.gz cd pycurl-7.19.3.1 python setup.py install --curl-config=/usr/local/bin/curl-config #校驗安裝結果以下: >>> import pycurl >>> pycurl.version 'PycURL/7.43.0.2 libcurl/7.36.0 OpenSSL/1.0.1e zlib/1.2.3'
pycurl.globalz_init(option):初始化curl環境app
選項能夠是常量之一:pycurl.GLOBAL_SSL pycurl.GLOBAL_WIN32 pycurl.GLOBAL_ALL pycurl.GLOBAL_NOTHING pycurl.GLOBAL_DEFAULT curl
對應於libcurl中的curl_global_init函數
pycurl.global_cleanup():清理curl環境,對應於libcurl中的curl_global_cleanup
pycurl.version:顯示pycurl版本信息以及libcurl,openSSL,zlib依賴項的版本信息,對應libcurl中的curl_version
pycurl.version_info():用元祖返回版本信息,對應libcurl中的curl_version_info
class pycurl.Curl:建立一個新的curl對象,它對應libcurl中的句柄.
class pycurl.CurlMulti:建立一個與libcurl中的句柄相對應的新curlMulti對象curlM
class pycurl.CurlShare:建立一個與libcurl中的句柄相對應的新CurlShare對象curlSH
class pycurl.Curl:建立一個新的curl對象
curl對象具備如下方法:
close():關閉句柄並結束curl會話
setopt(option,vlaue):設置curl會話選項,對應於libcurl中的curl_easy_setopt
option指定要設置的選項,pycurl定義了與curlopt_*libcurl中的常量相對應的常量,但CURLOPT_前綴被刪除
perform():執行文件傳輸,對應於libcurl中的curl_easy_perform,失敗時會引起pycurl.error異常
perform_rb():執行文件傳輸並將響應主體返回爲字節字符串,此方法將響應正文保存在StringIO(python 2)或BytelsIO(python 3)實例中,而後調用執行文件傳輸,返回str或者bytes實例,傳輸錯誤將引起pycurl.error異常。
perform_rs():以字符串形式執行文件傳輸並返回響應正文,
在Python 2中,此方法將響應正文保存在一個StringIO實例中,而後調用執行 文件傳輸,而後返回StringIO實例的值。此行爲與perform_rb相同。
在Python 3中,此方法將響應正文保存在BytesIO實例中,而後調用執行 文件傳輸,而後使用Python的默認編碼解碼響應正文,並將解碼的正文做爲Unicode字符串(str實例)返回
getinfo(option):
從curl會話中提取並返回信息,在調用時使用Python的默認編碼解碼字符串數據。對應於libcurl中的curl_easy_getinfo。getinfo除非perform被調用並完成,不然不該調用該方法 。
option選項是一個常數,對應CURLINFO_*於libcurl中的一個 常量。大多數選項不變名稱與相應的CURLINFO_*與恆定的名字CURLINFO_去掉前綴,例如CURLINFO_CONTENT_TYPE是訪問 pycurl.CONTENT_TYPE
getinfo_raw(option):
從curl會話中提取並返回信息,將字符串數據做爲字節字符串返回。對應於libcurl中的curl_easy_getinfo。getinfo_raw除非perform被調用並完成,不然不該調用該方法
reset():將在curl句柄上設置的全部選項重置爲默認值,但保留活動鏈接,會話ID緩存,DNS緩存,Cookie和共享。
unsetopt(option):將捲曲會話選項重置爲其默認值
Class pycurl.CurlMulti :建立一個與libcurl中的句柄相對應的新CurlMulti對象curlM
CurlMulti對象的方法:
close():關閉對象應用
add_handle(curl object):將一個現有和有效的curl對象添加到curlMulti對象中
remove_handle(curl object):從curlMulti對象中移除現有的有效curl對象
perform():狀態元組和活動curl對象的數量
setopt(option,value):設置curl多選項,option選項指定要設置的選項,pycurl定義了與curlmopt_*libcurl中的常量相對應的常量,但curlmopt_前綴被替換爲m_前綴,例如,CURLMOPT_PIPELINING在PycURL中公開爲pycurl.M_PIPELINING
fdset():具備活動文件描述符的列表元祖,可讀寫
timeout():返回等待操做的時間
要使用PycURL發佈網絡請求,須要如下步驟:
(1)建立一個pycurl.Curl市裏
(2)使用setopt設置選項
(3)經過perform來執行操做
(4)賽選得到資源
例1:簡單得到網絡資源
#!/usr/bin/env python #coding:utf8 import pycurl from io import BytesIO buffer = BytesIO() #建立緩存對象 c = pycurl.Curl() #建立curl實例 c.setopt(c.URL,'http://www.cnblogs.com/zhangxinqi/') #設置資源路徑 c.setopt(c.WRITEDATA,buffer) #設置資源數據寫入到緩存對象 c.perform() #執行 c.close() body=buffer.getvalue().decode() #讀取緩存中的資源並解碼 print(body)
例2:獲取https網絡資源
#!/usr/bin/env python #coding:utf8 import pycurl import certifi #導入根證書集合,用於驗證SSL證書可信和TLS主機身份 from io import BytesIO buffer = BytesIO() c = pycurl.Curl() c.setopt(c.URL,'https://www.w3cschool.cn/python/') c.setopt(c.WRITEDATA,buffer) c.setopt(c.CAINFO,certifi.where()) #設置指定證書驗證包 c.perform() c.close() body=buffer.getvalue() print(body.decode('utf-8'))
例3:獲取網站編碼自動解碼
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/6/6 9:21 # @Author : Py.qi # @File : pycurl_auto.py # @Software: PyCharm import certifi import pycurl import re try: from io import BytesIO except ImportError: from io import StringIO as BytesIO headers = {} def header_function(header_line): #python3上須要解碼 header_line = header_line.decode('iso-8859-1') if ':' not in header_line: return name, value = header_line.split(':', 1) name = name.strip() value = value.strip() name = name.lower() headers[name] = value url1 = 'http://www.mytju.com/classcode/tools/encode_gb2312.asp' url2 = 'http://psutil.readthedocs.io/en/latest/' url3 = 'https://www.cnblogs.com/ddxueyu/archive/2015/07/11/4638414.html' buffer = BytesIO() c = pycurl.Curl() c.setopt(c.URL,url2) c.setopt(c.CAINFO,certifi.where()) c.setopt(c.WRITEFUNCTION, buffer.write) c.setopt(c.HEADERFUNCTION, header_function) #頭文件返回給函數 c.perform() c.close() body = buffer.getvalue() encoding = None print(headers) if 'content-type' in headers: content_type = headers['content-type'].lower() print(content_type) match = re.search('charset=(\S+)', content_type) print(match) if match: encoding = match.group(1) print('Decoding using %s' % encoding) else: patt = re.search(r'charset=\"(\S+)\"',str(body)) encoding=patt.group(1).lower() print('Decoding using %s' % encoding) else: encoding = 'iso-8859-1' print(encoding) print(body.decode(encoding))
例4:響應信息寫入文件
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/6/6 10:20 # @Author : Py.qi # @File : pycurl_writeFiel.py # @Software: PyCharm import pycurl with open('out.html','wb') as f: c = pycurl.Curl() c.setopt(pycurl.URL,'http://www.quanjing.com/') c.setopt(pycurl.WRITEDATA,f) #配置響應內容寫入到文件 c.perform() c.close()
例5:使用 pycurl 的 setopt 與 getinfo 方法實現 HTTP 服務質量的探測
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/6/6 10:38 # @Author : Py.qi # @File : check_pycurl.py # @Software: PyCharm import pycurl from io import BytesIO class ex_response(object): def __init__(self,url): self.buffer = BytesIO() self.c = pycurl.Curl() self.c.setopt(pycurl.URL,url) self.c.setopt(pycurl.WRITEDATA, self.buffer) self.c.setopt(pycurl.WRITEHEADER,self.buffer) try: self.c.perform() except Exception as e: print('connection error:' + str(e)) self.buffer.close() self.c.close() def getinfo(self): h1 = self.c.getinfo(pycurl.HTTP_CODE) # 狀態碼 h2 = self.c.getinfo(pycurl.TOTAL_TIME) # 傳輸結束總消耗時間 h3 = self.c.getinfo(pycurl.NAMELOOKUP_TIME) # DNS解析時間 h4 = self.c.getinfo(pycurl.CONNECT_TIME) # 創建鏈接時間 h5 = self.c.getinfo(pycurl.PRETRANSFER_TIME) # 創建鏈接到準備傳輸消耗時間 h6 = self.c.getinfo(pycurl.STARTTRANSFER_TIME) # 從創建鏈接到傳輸開始消耗時間 h7 = self.c.getinfo(pycurl.REDIRECT_TIME) # 重定向消耗時間 h8 = self.c.getinfo(pycurl.SIZE_UPLOAD) # 上傳數據包大小 h9 = self.c.getinfo(pycurl.SIZE_DOWNLOAD) # 下載數據包大小 h10 = self.c.getinfo(pycurl.SPEED_DOWNLOAD) # 平均下載速度 h11 = self.c.getinfo(pycurl.SPEED_UPLOAD) # 平均上傳速度 h12 = self.c.getinfo(pycurl.HEADER_SIZE) # http頭文件大小 info =''' http狀態碼:%s 傳輸結束總時間:%.2f ms DNS解析時間:%.2f ms 創建鏈接時間:%.2f ms 準備傳輸時間:%.2f ms 傳輸開始時間:%.2f ms 重定向時間:%.2f ms 上傳數據包大小:%d bytes/s 下載數據包大小:%d bytes/s 平均下載速度:%d bytes/s 平均上傳速度:%d bytes/s http頭文件大小:%d byte ''' %(h1,h2*1000,h3*1000,h4*1000,h5*1000,h6*1000,h7*1000,h8,h9,h10,h11,h12) print(info) self.buffer.close() self.c.close() if __name__ == '__main__': curl_respon = ex_response("http://pycurl.io/") curl_respon.getinfo()
例6:發送表單數據
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/6/6 12:23 # @Author : Py.qi # @File : from_pycurl.py # @Software: PyCharm import pycurl from urllib.parse import urlencode c = pycurl.Curl() c.setopt(c.URL,'http://192.168.146.140/home/') post_data = {'username':'china','password':'7777','age':'18','salary':'999999'} postfields = urlencode(post_data) #表單數據編碼 c.setopt(pycurl.POSTFIELDS,postfields) #POSTFIELDS自動以POST的方式提交併請求發送數據 c.perform() c.close()
例7:文件上傳
HTML表單中文件上傳的行爲,使用HTTPPOST選項,FORM_FILE指定文件路徑。
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/6/6 13:22 # @Author : Py.qi # @File : httppost_pycurl.py # @Software: PyCharm import pycurl c=pycurl.Curl() c.setopt(c.URL,'http://192.168.146.140/home/') #HTTPPOST選項是經過POST請求來執行文件上傳,fileupload指定上傳文件字段,使用c.FORM_FILE來指定文件位置 c.setopt(c.HTTPPOST,[ ('fileupload',(c.FORM_FILE,'/home/image.jpg',)), ] ) c.perform() c.close()
例8:使用FORM_FILENAME設置文件名,FORM_CONTENTTYPE指定文件內容類型,來調整文件名和類型上傳文件
import pycurl c = pycurl.Curl() c.setopt(c.URL, 'http://192.168.146.140/home/') c.setopt(c.HTTPPOST, [ ('fileupload', ( #指定文件路徑 c.FORM_FILE, __file__, # 設置文件名 c.FORM_FILENAME, 'helloworld.py', # 設置文件類型 c.FORM_CONTENTTYPE, 'application/x-python', )), ]) c.perform() c.close()
例9:內存中文件數據上傳,使用BUFFER和BUFFERPTR
import pycurl c = pycurl.Curl() c.setopt(c.URL, 'http://192.168.146.140/home/') c.setopt(c.HTTPPOST, [ ('fileupload', ( c.FORM_BUFFER, 'readme.txt', c.FORM_BUFFERPTR, 'This is a fancy readme file', )), ]) c.perform() c.close()
例10:直接經過物理文件排列進行上傳
import pycurl c = pycurl.Curl() c.setopt(c.URL, 'http://192.168.146.140/home/') c.setopt(c.UPLOAD, 1) file = open('body.json') #讀取文件 c.setopt(c.READDATA, file) #直接上傳文件 c.perform() c.close() file.close()
例11:經過緩存數據上傳
import pycurl from io import BytesIO c = pycurl.Curl() c.setopt(c.URL, 'http://192.168.146.140/home/') c.setopt(c.UPLOAD, 1) data = '{"json":true}' #在緩存中讀取的數據須要解碼在python3中 buffer = BytesIO(data.encode('utf-8')) c.setopt(c.READDATA, buffer) #設置上傳 c.perform() c.close()
---------------------------------------------------------------------------------------------end