4

Golang学习之POST请求

 2 years ago
source link: https://co5mos.github.io/2019/11/15/go-post/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Golang学习之POST请求

发表于 2019-11-15

| 分类于 编程之道

我终于失去了你,在拥挤的人群中。

最近在用 Python 写爬虫, 然后就想用 Go 写一写, 然后稀里糊涂的发现这个站有一个接口可以直接请求数据, 那还爬啥啊, 请求吧。

然后发现不会写 POST 接口, 简直菜的抠脚。

其实也没啥, 就是有一个坑, 请求头必须要设定Content-Type为application/x-www-form-urlencoded,post参数才可正常传递。然后就没啥了。

所有代码仅作为学习啊。

package main

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

func fetch(targetURL string, i int, ch chan bool) {
fmt.Println("[+] Fetch URL", targetURL)

data := url.Values{
"codeId": {""},
"page": {strconv.Itoa(i)},
"size": {"100"},
"fileType": {""},
"channelWebPath": {""},
"channelLevels": {""}}
body := strings.NewReader(data.Encode())

req, _ := http.NewRequest("POST", targetURL, body)

req.Header.Set("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

client := &http.Client{}
resp, err := client.Do(req)

if err != nil {
log.Fatal("Http get err:", err)
}

if resp.StatusCode != 200 {
log.Fatal("Http status code:", resp.StatusCode)
}

defer resp.Body.Close()

respBody, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(respBody))

ch <- true

}

func main() {
start := time.Now()
url := ""
ch := make(chan bool)

for i := 1; i < 100; i++ {
go fetch(url, i, ch)
}

for i := 1; i < 100; i++ {
<-ch
}

elapsed := time.Since(start)
fmt.Printf("Took %s", elapsed)
}

请求头必须要设定Content-Type为application/x-www-form-urlencoded,post参数才可正常传递。

goroutine的用法

这里有一个关于 goroutine 的用法问题。

这个东西是啥就不BB了。

有没有像Python多进程/线程的那种等待子进/线程执行完的join方法呢?当然是有的,可以让 Go 协程之间信道(channel)进行通信:从一端发送数据,另一端接收数据,信道需要发送和接收配对,否则会被阻塞:

func fetch(targetURL string, i int, ch chan bool) {
...
ch <- true
}

func main() {
start := time.Now()
url := ""
ch := make(chan bool)

for i := 1; i < 100; i++ {
go fetch(url, i, ch)
}

for i := 1; i < 100; i++ {
<-ch
}

elapsed := time.Since(start)
fmt.Printf("Took %s", elapsed)
}

而在main函数中,在用一个for循环,<- ch 会等待接收数据(这里只是接收,相当于确认任务完成)。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK