Golang:Grequests 库的使用
Go 语言版本的 request
Go 语言内置的请求库 net/http 非常的优秀,但是在代码封装上却不尽完美
对于我这种习惯于用 Python 写爬虫的人来说,如果能有像 Requests 的 Py 库的 Go 版本实现那是再好不过了
所以 Grequests 就诞生了。
安装
go get -u github.com/levigross/grequests
其次,在语法格式上也是遵循 Py 库来封装的,直接来看它的用法
准备了一个模拟登录的 demo
package main
import (
"encoding/json"
"fmt"
//go语言版本的jquery
//"github.com/PuerkitoBio/goquery"
//"os"
//"sync"
//"strings"
//go语言版本的request
"github.com/levigross/grequests"
)
func login_post(log_url, user string, session *grequests.Session) (resp *grequests.Response){
resp, err := session.Post(log_url,
&grequests.RequestOptions{
Data: map[string]string{
"mobile": user,
"password": "password",
},
Headers: map[string]string{
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8",
"Connection": "keep-alive",
"Content-Length":"69",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
},
})
if err == nil && resp.StatusCode == 200 {
fmt.Println("登录成功!", resp)
return resp
}
fmt.Println("出错")
return resp
}
func yuyue(yuyue_url string, goods_id int, session *grequests.Session) (resp *grequests.Response){
param := make(map[interface{}]interface{})
mapString := make(map[string]string)
param["i"] = 143
param["c"] = "entry"
param["do"] = "member"
param["m"] = "sz_yi"
param["p"] = "index"
param["op"] = "buy"
param["type"] = "bespeak"
param["id"] = goods_id
//fmt.Println(param)
for key, value := range param {
strKey := fmt.Sprintf("%v", key)
strValue := fmt.Sprintf("%v", value)
mapString[strKey] = strValue
}
fmt.Println(mapString)
resp, err := session.Get(yuyue_url,
&grequests.RequestOptions{
Headers: map[string]string{
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36",
},
Params:mapString,
//Params: map[string]string{
// "i": "143",
// "c": "entry",
// "do": "member",
// "m": "sz_yi",
// "p": "index",
// "op": "buy",
// "type": "bespeak",
// "id": goods_id,
//},
})
if err == nil && resp.StatusCode == 200 {
fmt.Println("预约成功!", resp)
return resp
}
return resp
}
func main() {
var d map[string]interface{}
session := grequests.NewSession(nil) //建立session会话
//fmt.Printf("%T",session)
login_post("http://www.xxx.xxx/login","123456789100",session)
yuyue_result := yuyue("http://www.xxx.xxx/index.php",1,session)
//jjjj := []byte(yuyue_result.Bytes())
//fmt.Println(string(jjjj))
json.Unmarshal([]byte(yuyue_result.Bytes()), &d) //转换成json格式
fmt.Println(d["result"])
}
其实我建议先把 文档看一遍,尝试这写两遍,使用起来就比较顺手了
首先要建立 Session 来保证登陆以及之后的操作来自同一个会话,并且作为参数传入
headers 和 params参数 采用 map 传入
可以看到 resp.StatusCode 之类的语法和 Py 的 requests 非常相似,实际上底层就是 requests
怎么说呢,Py 和 Go 都是开源语言,如果你需要更改源码让代码更强大,可以大胆的去做
原生库
那么,如果不使用 Grequests 的话该如何写呢?
简单贴一下代码
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
func login(log_url,user string) (*http.Client){
//params := url.Values{}
//params.Add("memberAccount", "xxx")
//params.Add("memberUmm", "haha")
//params.Add("check", captcha)
payload := url.Values{"mobile": {user}, "password": {"password"}}
//申明一个客户端 或者 使用默认
client := &http.Client{}
req, err := http.NewRequest(
"POST",
log_url,
strings.NewReader(payload.Encode()), //strings.NewReader(params.Encode()))
)
if err != nil {
panic(err)
}
req.Header.Add("Accept", "application/json, text/javascript, */*; q=0.01")
req.Header.Add("Accept-Encoding", "gzip, deflate")
req.Header.Add("Connection", "keep-alive")
req.Header.Add("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36")
req.Header.Add("X-Requested-With", "XMLHttpRequest")
r, _ := client.Do(req)
defer func() { _ = req.Body.Close() }()
body, _ := ioutil.ReadAll(r.Body)
fmt.Printf("%s", body)
fmt.Printf("%T",req)
//cookie := r.Cookies()
//fmt.Println(cookie)
return client
}
func main() {
//get()
client := login("http://www.xxx.xxx/login","123456789100")
fmt.Printf("%T",client)
}
大概是这样的,原生库有几种写法,具体的就不写了
找个时间写写 go 的爬虫并发
欢迎转载,但要声明出处,不然我顺着网线过去就是一拳。
个人技术博客:http://www.gzky.live
有疑问加站长微信联系(非本文作者)