由于tornado內置的AsyncHTTPClient功能過于單一, 所以自己寫了一個基于Tornado的HTTP客戶端庫, 鑒于自己多處使用了這個庫, 所以從項目中提取出來, 寫成一個單獨庫 tornadohttpclient
TornadoHTTPClient 是一個基于Tornado的高效的異步HTTP客戶端庫, 支持Cookie和代理, 目前僅在Python2.7平臺上測試過, 不支持Python3
聽取了仙子君的意見, 直接對tornado.curl_httpclient.CurlAsyncHTTPClient進行封裝
安裝
首先從git clone 下代碼
1
|
git clone https: //github .com /coldnight/tornadohttpclient .git |
然后安裝它
1
2
|
cd tornadohttpclient python setup.py install |
教程
GET
TornadoHTTPClient的get方法可以發起一個get請求
1
2
3
4
5
6
7
8
9
10
|
from tornadohttpclient import TornadoHTTPClient # 實例化 http = TornadoHTTPClient() # 發出get請求 http.get( "http://www.linuxzen.com" ) # 開始主事件循環 http.start() |
POST
TornadoHTTPClient的post方法可以發起一個post請求
讀取響應
上面僅僅發出了請求, 但是我們無法讀取GET請求回來的數據, 我們可以使用一個回調來讀取響應
1
2
3
4
5
6
7
8
9
10
|
from tornadohttpclient import TornadoHTTPClient http = TornadoHTTPClient() def callback(response): print response.body http.stop() http.get( "http://www.linuxzen.com" , callback = callback) http.start() |
通過callback關鍵字參數我們可以傳進一個回調函數, 當請求成功時會調用此函數, 并給此函數傳遞一個與urllib2.urlopen返回一樣的reponse實例
上傳文件
upload方法可以上傳文件, 其接受一個url和文件的field和文件路徑, 還有其他post參數
1
2
3
4
5
6
7
8
9
10
11
|
from tornadohttpclient import TornadoHTTPClient http = TornadoHTTPClient() def callback(response): print ( "打開圖片鏈接" , end = " " ) print (response.effective_url) http.stop() http.upload( "http://paste.linuxzen.com" , "img" , "img_test.png" , callback = callback) http.start() |
給callback傳遞參數
有時候callback可能需要訪問局部變量, 可以通過 args和kwargs關鍵字參數, 將callback的參數傳遞給get/post方法, args參數將會在response參數之后被傳遞, args參數類型應當是一個元組, kwargs參數類型應當是一個字典
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
from tornadohttpclient import TornadoHTTPClient http = TornadoHTTPClient() def callback(response, times): print response.body print times if times = = 9 : http.stop() for i in range ( 10 ): http.get( "http://www.linuxzen.com" , callback = callback, args = (i, )) http.start() |
發送延遲請求
有時我們需要延遲幾秒也發送請求或每隔幾秒就發送一個請求, get/post方法的delay關鍵字參數可以解決, delay參數接受一個單位為秒的數字, 并延遲delay秒后發起請求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from tornadohttpclient import TornadoHTTPClient http = TornadoHTTPClient() def callback(response, times): print response.body if times < 9 : # 延遲10秒發送此請求 http.get( "http://www.linuxzen.com" , callback = callback, args = (times + 1 , ), delay = 10 ) else : http.stop() http.get( "http://www.linuxzen.com" , callback = callback, args = ( 1 , )) http.start() |
給請求傳遞參數
TornadoHTTPClient 的 get/post方法的第二個參數params可以定義請求時傳遞的參數params的類型為字典或者((key, value), )類型的元組或列表,例如使用百度搜索TornadoHTTPClient
1
2
3
4
5
6
7
8
9
10
|
from tornadohttpclient import TornadoHTTPClient http = TornadoHTTPClient() def callback(response): print response.body http.stop() http.get( "http://www.baidu.com/s" , (( "wd" , "tornado" ),), callback = callback) http.start() |
以上也使用與POST方法, 比如登錄網站
1
2
3
4
5
6
7
8
9
10
11
|
from tornadohttpclient import TornadoHTTPClient http = TornadoHTTPClient() def callback(response): print response.body http.stop() http.post( "http://ip.or.domain/login" , (( "username" , "cold" ), ( "password" , "pwd" )), callback = callback) http.start() |
指定HTTP頭
TornadoHTTPClient 的get/post方法的 headers關鍵字參數可以自定額外的HTTP頭信息, 參數類型為一個字典
指定User-Agent頭
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from tornadohttpclient import TornadoHTTPClient http = TornadoHTTPClient() def callback(response): print response.body http.stop() headers = dict ((( "User-Agent" , "Mozilla/5.0 (X11; Linux x86_64)" \ " AppleWebKit/537.11 (KHTML, like Gecko)" \ " Chrome/23.0.1271.97 Safari/537.11" ), )) http.get( "http://www.linuxzen.com" , headers = headers, callback = callback) |
使用代理
TornadoHTTPClient 的set_proxy方法可以設置代理, 其接受兩個參數, 分別是代理的 主機名/ip 代理的端口, unset_proxy可以取消代理
1
2
3
4
5
6
7
8
9
10
11
12
|
from tornadohttpclient import TornadoHTTPClient http = TornadoHTTPClient() def callback(response): print response.body http.unset_proxy() http.stop() http.set_proxy( "127.0.0.1" , 8087 ) http.get( "http://shell.appspot.com" , callback = callback) http.start() |
Cookie
TornadoHTTPClient會自動記錄和裝載Cookie, 可以通過 TornadoHTTPClient實例屬性 cookie 獲取Cookie