go 语言一直是我在部门里进行产品开发的后端选择,也经常会用 golang 进行一些爬虫工作,于是就打算写一篇博客总结一下如何用 golang 发送 http 请求。

GET 请求

基本的 GET 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import (
"fmt"
"io/ioutil"
"net/http"
)

func main() {
resp, err := http.Get("https://blog.cnpatrickstar.com/get")
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
fmt.Println(resp.StatusCode)
if resp.StatusCode == 200 {
fmt.Println("ok")
}
}

带参数的 GET 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)

func main(){
params := url.Values{}
Url, err := url.Parse("https://blog.cnpatrickstar.com/get")
if err != nil {
return
}
params.Set("name","patrick")
params.Set("age","20")
// 如果参数中有中文参数,这个方法会进行 URLEncode
Url.RawQuery = params.Encode()
urlPath := Url.String()
fmt.Println(urlPath)
// https://blog.cnpatrickstar.com/get?age=20&name=patrick
// 当然也可以直接用拼接好的 url 进行请求,但业务场景下大多还是用变量的形式拼接的
resp,err := http.Get(urlPath)
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}

带请求头的 GET 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import (
"fmt"
"io/ioutil"
"net/http"
)

func main() {
client := &http.Client{}
req,_ := http.NewRequest("GET","https://blog.cnpatrickstar.com/get",nil)
req.Header.Add("name","patrick")
req.Header.Add("age","20")
resp,_ := client.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf(string(body))
}

解析返回的 JSON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)

type result struct {
Args string `json:"args"`
Headers map[string]string `json:"headers"`
Origin string `json:"origin"`
Url string `json:"url"`
}

func main() {
resp, err := http.Get("https://blog.cnpatrickstar.com/get")
if err != nil {
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
var res result
_ = json.Unmarshal(body,&res)
fmt.Printf("%#v", res)
}
POST 请求

基本的 POST 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)

func main() {
form := url.Values{}
form.Add("name","patrick")
form.Add("age","20")
resp, _ := http.PostForm("https://blog.cnpatrickstar.com/post",form)
// "Content-Type": "application/x-www-form-urlencoded"
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}

另外一种内容格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
)

func main() {
urlValues := url.Values{
"name":{"patrick"},
"age":{"20"},
}
reqBody:= urlValues.Encode()
resp, _ := http.Post("https://blog.cnpatrickstar.com/post", "text/html",strings.NewReader(reqBody))
// "Content-Type": "text/html"
body,_:= ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}

发送 JSON 的 POST 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)

func main() {
client := &http.Client{}
data := make(map[string]interface{})
data["name"] = "patrick"
data["age"] = "20"
bytesData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST","https://blog.cnpatrickstar.com/post",bytes.NewReader(bytesData))
resp, _ := client.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}

不用 client 的 POST 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)

func main() {
data := make(map[string]interface{})
data["name"] = "patrick"
data["age"] = "20"
bytesData, _ := json.Marshal(data)
resp, _ := http.Post("https://blog.cnpatrickstar.com/post","application/json", bytes.NewReader(bytesData))
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}