教程
1. 发起请求
你可以像这样发起一个请求:
resp, err := dw.Get("https://httpbin.org/get")
if err != nil {
return
}
如果 err 等于 nil,那么你会得到一个 Response
对象。
其他请求方法:
resp, err := dw.Post("https://httpbin.org/post", dw.NewPostForm("key", "value"))
resp, err := dw.Head("https://httpbin.org/head")
resp, err := dw.Put("https://httpbin.org/put", dw.NewPostForm("key", "value"))
resp, err := dw.Delete("https://httpbin.org/delete")
你还可以使用一个更加通用的函数 Send()
来发起请求,使用这个方法需要你先构造一个 Request
对象:
req, err := dw.NewRequest("Get", "https://httpbin.org/get")
if err != nil {
return
}
resp, err := dw.Send(req)
if err != nil {
return
}
使用这种方法发起请求,那么 Request
对象将是可以被复用的。除了需要将请求方法的字符串作为第一个参数传入之外,NewRequest()
方法与普通的 Get()
和 Post()
等方法需要的参数是一致的。
2. 传递URL参数
在请求中加入URL参数非常简单,你只需要使用 NewParams()
创建一个URL参数对象,并将其传入请求方法中即可:
params := dw.NewParams("key", "value")
resp, err := dw.Get("https://httpbin.org/get", params)
if err != nil {
return
}
fmt.Println(resp.URL)
输出:
https://httpbin.org/get?key=value
如果希望传入多个参数,可以像这样:
params := dw.NewParams(
"key1", "value1",
"key2", "value2",
)
注:记住 Key 和 Value 之间的逗号。
注:Key 必须与 Value 成对匹配, 如果没有的话将会报错。
参数中有同名的 Key 是没有问题的:
params := dw.NewParams(
"key1", "value1",
"key1", "value2",
)
输出:
https://httpbin.org/get?key1=value1&key1=value2
3. 设置 Headers
设置 Headers 与传入URL参数非常相似, 使用 NewHeaders()
:
headers := dw.NewHeaders(
"key", "value",
"User-Agent", "direwolf",
)
resp, err := dw.Get("https://httpbin.org/get", headers)
if err != nil {
return
}
fmt.Println(resp.Text())
输出:
{
"args": {},
"headers": {
"Accept-Encoding": "gzip",
"Host": "httpbin.org",
"Key": "value",
"User-Agent": "direwolf"
},
"origin": "1.1.1.1, 1.1.1.1",
"url": "https://httpbin.org/get"
}
这个 NewHeaders()
方法返回的是一个 http.Header
对象,如果你想要自己构造也是可以的。
如果你没有设置 User-Agent
,direwolf 会自动使用默认的 User-Agent
: direwolf - winter is coming
。
4. 添加 Cookies
添加 Cookies 与传入URL参数也是类似的:
cookies := dw.NewCookies(
"key1", "value1",
"key2", "value2",
)
resp, err := dw.Get("https://httpbin.org/get", cookies)
if err != nil {
return
}
fmt.Println(resp.Text())
输出:
{
"args": {},
"headers": {
"Accept-Encoding": "gzip",
"Cookie": "key2=value2; key1=value1",
"Host": "httpbin.org",
"User-Agent": "direwolf - winter is coming"
},
"origin": "1.1.1.1, 1.1.1.1",
"url": "https://httpbin.org/get"
}
5. Post 表单
如果你想要使用 Post 方法提交表单,请使用 NewPostForm()
:
postForm := dw.NewPostForm(
"uid", "123456789",
"pw", "666888",
)
resp, err := dw.Post("https://httpbin.org/post", postForm)
if err != nil {
return
}
fmt.Println(resp.Text())
输出:
{
"args": {},
"data": "",
"files": {},
"form": {
"pw": "666888",
"uid": "123456789"
},
"headers": {
"Accept-Encoding": "gzip",
"Content-Length": "23",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "direwolf - winter is coming"
},
"json": null,
"origin": "1.1.1.1, 1.1.1.1",
"url": "https://httpbin.org/post"
}
6. Post 请求体
如果你想要使用 Post 直接提交数据,你可以使用 Body
,它的原始类型是 []byte
,如下所示:
body := dw.Body("Hello World")
resp, err := dw.Post("https://httpbin.org/post", body)
if err != nil {
return
}
fmt.Println(resp.Text())
输出:
{
"args": {},
"data": "Hello World",
"files": {},
"form": {},
"headers": {
"Accept-Encoding": "gzip",
"Content-Length": "11",
"Host": "httpbin.org",
"User-Agent": "direwolf - winter is coming"
},
"json": null,
"origin": "1.1.1.1, 1.1.1.1",
"url": "https://httpbin.org/post"
}
7. 设置超时
Timeout
指定了一个请求的超时时间,这个超时包含了连接时间、任何的重定向、和读取响应体的时间。
计时器在 Get、Head、Post 等方法返回之后仍在运行,并且可能会打断 Response.Body 的读取,在 Response.Body 读取完毕后计时结束。
- 如果 timeout > 0, 表示设置了一个超时时间。
- 如果 timeout = 0 或者没有设置超时, 表示使用默认的30秒超时。
timeout := dw.Timeout(5)
resp, err := dw.Get("https://httpbin.org/delay/10", timeout)
或者
resp, err := dw.Get(
"https://httpbin.org/delay/10",
dw.Timeout(5),
)
8. 重定向
RedirectNum 是允许重定向的次数。
-
如果 RedirectNum > 0, 表示设置一个允许重定向的次数。
-
如果 RedirectNum = 0 或者没有设置 RedirectNum, 表示默认允许10次重定向。
-
如果 RedirectNum < 0, 表示禁止重定向。
redirect := dw.RedirectNum(10)
resp, err := dw.Get("https://httpbin.org/delay/10", redirect)
或者
resp, err := dw.Get(
"https://httpbin.org/delay/10",
dw.RedirectNum(10),
)
9. 代理
设置代理同样非常简单,你可以为 HTTP 和 HTTPS 网页分别设置不同的代理:
proxies := &dw.Proxy{
HTTP: "http://127.0.0.1:8888",
HTTPS: "http://127.0.0.1:8888",
}
resp, err := dw.Get("https://httpbin.org/get", proxies)
if err != nil {
return
}
fmt.Println(resp.Text())
如果没有设置代理,那么将使用默认的环境代理。
10. Response 响应
发起请求之后,如果没有返回异常,那么你会得到一个 Response
对象。
你可以从 response 得到原始的请求地址:
resp.URL
也可以获取请求的状态码, 仅数字部分:
resp.StatusCode
获取请求返回的 headers:
resp.Headers
获取请求返回的 cookies:
resp.Cookies
获取得到这个响应的请求:
resp.Request
11. 提取数据
你使用 direwolf 发送请求之后可以非常方便的提取数据,正如我们上面所做的一样:
resp, err := dw.Get("https://httpbin.org/get")
if err != nil {
return
}
fmt.Println(resp.Text())
direwolf
会默认使用 UTF8
编码来解码内容。你也可以使用 Encoding()
方法自行指定解码的编码,此方法会返回当前正在使用的解码方式。
resp.Encoding("GBK")
目前仅支持 UTF8
, GBK
, GB18030
, Latin1
这几种编码。
注:Text() 会在第一次被调用时解码内容并缓存结果。
text := resp.Text()
除此之外,如果你想要获取原始的 content,可以使用 Content
,这是一个 []byte
:
resp.Content
12. 使用 CSS 选择器提取数据
Text 文本
Direwolf 使用 goquery
在内部集成了 Css 选择器,可以使提取数据更加简单。
text := resp.CSS("a").Text()
这会查找所有符合匹配的数据结果, 将其放入一个切片中并返回。如果没有找到匹配的数据,它会返回一个空切片。
在很多情况下,我们仅仅查找一个单个的匹配结果, 这样我们可以使用 First()
或者 At()
来提取单个匹配结果:
text1 := resp.CSS("a").First().Text()
text2 := resp.CSS("a").At(3).Text()
使用这两个方法会返回单个的字符串,如果没有找到结果,会返回一个空字符串。
Text()
方法仅返回当前节点下的所有文本内容,不包含子节点中的文本。如果你需要所有子节点中的文本,请考虑 TextAll()
。
text := resp.CSS("a").TextAll()
Attribute 属性
除了文本内容,direwolf 也可以提取属性内容:
attr := resp.CSS("a").Attr("href")
与 Text()
相同,它返回一个包含属性值的切片。它也可以使用 First()
或者 At()
来提取单个数据。
Attr()
可以设置一个默认值,如果没有找到匹配的值,就会返回默认值。
attr := resp.CSS("a").Attr("class", "default value")
13. 使用正则提取数据
Direwolf 也支持使用正则表达式提取数据,有两个方法。
这是示例数据:
fmt.Println(resp.Text())
// Output:
// -Hello--World--direwolf--wnanbei-
首先是 Re()
,它返回一个包含所有匹配数据的列表。
fmt.Println(resp.Re("-.*?-"))
// Output:
// [-Hello- -World- -direwolf- -wnanbei-]
然后是 ReSubmatch()
,它会返回一个二维列表,包含着所有的子匹配结果(正则表达式里括号中匹配的数据)。
fmt.Println(resp.ReSubmatch("-(.*?)--(.*?)-"))
// Output:
// [[Hello World] [direwolf wnanbei]]