requests
requests
是一個用golang 語言clone python版本的requests庫。
golang 內建的net/http功能已經非常完善。它和python裡面的urllib系列庫一樣,功能足夠,但是使用起來非常繁瑣。
python版本的requests簡直就是神器,讓很多人非常敬仰。
因此我就動手按照python的requests的思想封裝了一個 requests。
動手之前,我想盡量相容 python的寫法。但是golang不支援函數名稱小寫,
也不支援 參數命名。所以我只能用參數類型的方案來支援動態參數。
安裝
golang 1.11之前
go get -u github.com/asmcos/requests
golang 1.11之後,編輯一個go.mod檔案
module github.com/asmcos/requests
!!! 特別說明
由於requests代碼在更新,所有例子都有是當前有效。
並且部分區段有上下文。請大家閱讀時參考原代碼的requests_test.go
開始使用(帶Auth)
package mainimport ( "github.com/asmcos/requests" "fmt")func main (){ req := requests.Requests() resp,_ := req.Get("https://api.github.com/user",requests.Auth{"asmcos","password...."}) println(resp.Text()) fmt.Println(resp.R.StatusCode) fmt.Println(resp.R.Header["Content-Type"])}
第一個例子為什麼是它? 因為python requests第一個例子是它。。。呵呵
注意::: `密碼` 和使用者名稱要用github真實使用者才能測試。
建立請求的方法
例子1
極簡使用
package mainimport "github.com/asmcos/requests"func main (){ resp,_ := requests.Get("http://go.xiulian.net.cn") println(resp.Text())}
其實 requests實現都是先用Requests()函數建立一個 request 和 client,
再用req.Get去請求。
requests.Get 是一個封裝,對Requests()和req.Get的一個封裝。
例子2
這個例子是分成2個步驟,來操作,這樣的好處是可以通過req來設定各種請求參數。
後面的例子會展示各種設定。
package mainimport "github.com/asmcos/requests"func main (){ req := requests.Requests() resp,_ := req.Get("http://go.xiulian.net.cn",requests.Header{"Referer":"http://www.jeapedu.com"}) println(resp.Text())}
設定Header
req := Requests()req.Header.Set("accept-encoding", "gzip, deflate, br")req.Get("http://go.xiulian.net.cn", requests.Header{"Referer": "http://www.jeapedu.com"})
!!! 設定頭的2種方法
1. 通過req.Header.Set函數直接設定
2. 調用req.Get 函數時,在函數參數裡填寫上
Get 支援動態參數,但是參數前面要加類型標識。
函數裡面根據類型判斷參數的含義。
其實 函數的參數裡關於Header參數是可以多次設定的。
url1 := "http://go.xiulian.net.cn"req.Get(url1, requests.Header{"k0": "v0"},requests.Header{"k1":"v1"},requests.Header{"k2":"v2"})h := requests.Header{ "k3":"v3", "k4":"v4", "k5":"v5",}req.Get(url1,h)
這些都可以。靈活增加頭。
設定參數
p := requests.Params{ "title": "The blog", "name": "file", "id": "12345",}resp,_ := Requests().Get("http://www.cpython.org", p)
其實參數設定。參數設定也是支援多次的。
類似如下:
resp,_ := Requests().Get("http://www.cpython.org", p,p1,p2)
POST 的form表單
data := Datas{ "comments": "ew", "custemail": "a@231.com", "custname": "1", "custtel": "2", "delivery": "12:45", "size": "small", "topping": "bacon", }resp,_ := req.Post("https://www.httpbin.org/post",data)fmt.Println(resp.Text())
!!!! 注意
Post的form是放在body裡面,而get的params 是放在url裡面。
Proxy
目前不支援帶密碼驗證的代理。
req = Requests()req.Proxy("http://192.168.1.190:8888")resp,_ = req.Get("https://www.sina.com.cn")
設定Cookies
requests 支援自身傳遞cookies。本質上是把cookies存在client.jar裡面。
使用者佈建的cookies也會隨著client.jar來傳遞。
req = Requests()cookie := &http.Cookie{}cookie.Name = "anewcookie"cookie.Value = "20180825"cookie.Path = "/"req.SetCookie(cookie)fmt.Println(req.Cookies)req.Get("https://www.httpbin.org/cookies/set?freeform=1234")req.Get("https://www.httpbin.org")req.Get("https://www.httpbin.org/cookies/set?a=33d")
!!! 過程說明
代碼中 首先使用http.Cookie產生一個使用者自訂的cooie,
req.SetCookie 實際上還沒有把cookie放在client.jar裡面。
在Get的時候requests會把req.Cookies裡面的內容複寫到client.jar裡面,並且清空req.cookies
再一次Get的時候,requests都會處理Cookies。
debug
當設定了Debug = 1,請求的時候會把request和response都列印出來,
包含request的cookie, 返回的cookie沒有列印。
req := Requests()req.Debug = 1data := Datas{ "comments": "ew", "custemail": "a@231.com", "custname": "1", "custtel": "2", "delivery": "12:45", "size": "small", "topping": "bacon", }resp,_ := req.Post("https://www.httpbin.org/post",data)fmt.Println(resp.Text())
Debug 結果如下
===========Go RequestDebug ============POST /post HTTP/1.1Host: www.httpbin.orgUser-Agent: Go-Requests 0.5Content-Length: 96Content-Type: application/x-www-form-urlencodedAccept-Encoding: gzip===========Go ResponseDebug ============HTTP/1.1 200 OKContent-Length: 560Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin: *Connection: keep-aliveContent-Type: application/jsonDate: Sun, 02 Sep 2018 09:40:32 GMTServer: gunicorn/19.9.0Via: 1.1 vegur{ "args": {}, "data": "", "files": {}, "form": { "comments": "ew", "custemail": "a@231.com", "custname": "1", "custtel": "2", "delivery": "12:45", "size": "small", "topping": "bacon" }, "headers": { "Accept-Encoding": "gzip", "Connection": "close", "Content-Length": "96", "Content-Type": "application/x-www-form-urlencoded", "Host": "www.httpbin.org", "User-Agent": "Go-Requests 0.5" }, "json": null, "origin": "219.143.154.50", "url": "https://www.httpbin.org/post"}
Authentication 驗證使用者名稱和密碼。
req = Requests()url1 := "https://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?0.45874470316137206"resp,_ = req.Get(url1,Auth{"httpwatch","foo"})fmt.Println(resp.httpresp)
使用者名稱和密碼的參數是加密存放在Header裡面,
和params是不同的。
saveFile
接著上面的例子,如果成功了。返回的資料實際是一個jpeg格式檔案。
我們可以直接存檔案。
resp.SaveFile("auth.jpeg")
JSON
req = Requests()req.Header.Set("Content-Type","application/json")resp,_ = req.Get("https://httpbin.org/json")var json map[string]interface{}resp.Json(&json)for k,v := range json{ fmt.Println(k,v)}
支援GZIP格式
req = Requests()req.Debug = 1resp,_ = req.Get("https://httpbin.org/gzip")fmt.Println(resp.Text())
支援傳檔案POST
req = Requests()req.Debug = 1path, _ := os.Getwd()path1 := path + "/../examples/net1.go"path2 := path + "/../examples/net2.go"resp,_ = req.Post("https://www.httpbin.org/post",data,Files{"a":path1,"b":path2})fmt.Println(resp.Text())
header,params,是不分 GET和POST的。
返回cookies
其實requests的cookies 一直存在client.jar裡面,
所以需要從client.jar讀取。
resp,_ = req.Get("https://www.httpbin.org")coo := resp.Cookies()// coo is [] *http.Cookiesprintln("********cookies*******")for _, c:= range coo{ fmt.Println(c.Name,c.Value)}