Go入門系列(十一)WEB

目錄
一、服務(wù)端
二、客戶端

一、服務(wù)端

什么是Web的服務(wù)端?個人理解:網(wǎng)站,API等。
Go語言里面提供了一個完善的net/http包,通過http包可以很方便的就搭建起來一個可以運行的Web服務(wù)。同時使用這個包能很簡單地對Web的路由,靜態(tài)文件,模版,cookie等數(shù)據(jù)進行設(shè)置和操作。
拉起一個http服務(wù)僅需要簡單的幾行,定義路由,定義方法即可:

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello world!")
}

func main() {
    http.HandleFunc("/", hello) //設(shè)置訪問的路由
    err := http.ListenAndServe(":8080", nil) //設(shè)置監(jiān)聽的端口
    checkErr(err)
}

func checkErr(err error) {
    if err != nil {
        fmt.Println(err.Error())
        return
    }
}

···
我們嘗試增加簡單的傳參交互:

func hello(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    if len(r.Form["name"])>0 {
        fmt.Fprintf(w, "Hello %s",r.Form["name"][0])
    }else {
        fmt.Fprintf(w, "WHo are u?")
    }
}

Golang Web開源框架已經(jīng)逐漸興起,感興趣的小伙伴可以自行了解。因為對于本章節(jié)來講此非重點,所以我們在這里僅進行簡單的web服務(wù)功能介紹。

二、客戶端

Web客戶端,如B/S架構(gòu)的瀏覽器,而對于滲透行業(yè)的需求,爬蟲,yes!
借助http包實現(xiàn)一個最基本的例子,以剛剛搭建的服務(wù)端為例,發(fā)起get請求:

func main() {
    resp, err := http.Get("http://127.0.0.1:8080")
    checkErr(err)
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

簡單的http請求可以借助http來實現(xiàn),但是更多的請求是需要校驗header頭的。
所以我們?nèi)绻枰O(shè)置其它參數(shù),就需要用到其組件了。

  • Client
    基本用法的話和http十分相似:
func main() {
    client := &http.Client{}
    resp, err := client.Get("http://127.0.0.1:8080")
    checkErr(err)
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

我們可以進入該組件查看其功能,分別對應(yīng)連接壽命管理,重定向控制,cookie對象管理和超時設(shè)置。

type Client struct {
    Transport RoundTripper
    CheckRedirect func(req *Request, via []*Request) error
    Jar CookieJar
    Timeout time.Duration
}

但是,該組件依然不能滿足我們對header頭的苛刻設(shè)置。

  • Request
    http提供了NewRequest方法來生成Request,此方法中做了一些生成Request的默認設(shè)置,函數(shù)簽名為:
func NewRequest(method, url string, body io.Reader) (*Request, error)

參數(shù)中method和url兩個是必備參數(shù),而body參數(shù),在使用沒有body的請求方法時,傳入nil即可。
設(shè)置完成后,借助client組建的Do()方法執(zhí)行。

req, err := NewRequest("GET", "https://127.0.0.1:8080", nil)
resp, err := client.Do(req)

寫到這里的時候,我他喵心疼已經(jīng)崩了,python他不香嘛,requests庫簡直強無敵。
emmmm,綜合對比一下,go語言的爬蟲代碼量和代碼難度(或者是設(shè)置項之多)可能要比python多個幾倍不止,尤其是Go語言的數(shù)據(jù)處理也比python相對復(fù)雜。優(yōu)點嘛,其并發(fā)機制決定著go的性能會更高,此外,go還有一點就是編譯為二進制文件的穩(wěn)定性,這個絕非python可以比擬的。
如果個人看法的話,非編程專業(yè)寫爬蟲還是python吧,當(dāng)然也包括我,至少目前的態(tài)度是這樣的。

更多更詳細的設(shè)置這里安利一篇比較棒的文章:http://www.itdecent.cn/p/4e53d4727152

既然學(xué)都學(xué)了,我們嘗試完成一個小任務(wù),完成一個疫情實時監(jiān)控小程序!
api的話,尋找一個實時更新的web界面即可,如:https://voice.baidu.com/act/newpneumonia/newpneumonia

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://voice.baidu.com/act/newpneumonia/newpneumonia", nil)
    checkErr(err)
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0")
    req.AddCookie(&http.Cookie{Name: "BAIDUID",Value: "00A1B1EC9FF50D09E8740C2BB49A2120"})
    resp, err := client.Do(req)
    checkErr(err)
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    summaryDataIn := regexp.MustCompile(`"summaryDataIn":{.*?}`).FindAllStringSubmatch(string(body), -1)[0][0]
    fmt.Println("【疫情實時報告】")
    fmt.Println("現(xiàn)有確診:",regexp.MustCompile(`"curConfirm":"(.*?)"`).FindAllStringSubmatch(summaryDataIn, -1)[0][1])
    fmt.Println("現(xiàn)有疑似:",regexp.MustCompile(`"unconfirmed":"(.*?)"`).FindAllStringSubmatch(summaryDataIn, -1)[0][1])
    fmt.Println("現(xiàn)有重癥:",regexp.MustCompile(`"icu":"(.*?)"`).FindAllStringSubmatch(summaryDataIn, -1)[0][1])
    fmt.Println("累計治愈:",regexp.MustCompile(`"cured":"(.*?)"`).FindAllStringSubmatch(summaryDataIn, -1)[0][1])
    fmt.Println("累計死亡:",regexp.MustCompile(`"died":"(.*?)"`).FindAllStringSubmatch(summaryDataIn, -1)[0][1])
    fmt.Println("累計確診:",regexp.MustCompile(`"confirmed":"(.*?)"`).FindAllStringSubmatch(summaryDataIn, -1)[0][1])
    fmt.Println("更新時間:",time.Now().Format("2006-01-02 15:04:05"))

}

func checkErr(err error) {
    if err != nil {
        fmt.Println(err.Error())
        return
    }
}

我們將源碼編譯為二進制文件,運行效果如下:

END

日常吐槽時間到,撇開爬蟲功能的優(yōu)劣,我想說的是我從沒想拿Golang替代python,但是它相對簡單的語法高效的性能,至少在WEB滲透方向的需求里,它在一定程度上可以替代C/C艸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Python語言特性 1 Python的函數(shù)參數(shù)傳遞 看兩個如下例子,分析運行結(jié)果: 代碼一: a = 1 def...
    時光清淺03閱讀 569評論 0 0
  • Python語言特性 1 Python的函數(shù)參數(shù)傳遞 看兩個如下例子,分析運行結(jié)果: 代碼一: a = 1 def...
    伊森H閱讀 3,177評論 0 15
  • 沙溪古鎮(zhèn) 青瓦白墻證古今,一條玉河流入心; 庯峭霓虹映紅顏,臨水傲立天地間; 穹宇妒羨君之顏,偷入水中見君顏; 試...
    隨筆詩文閱讀 327評論 0 1
  • 草長鶯飛,柳綠花紅,一眨眼就又要步入盛夏。去年的這個時候,我還滿懷希望和夢想,沒有高考的我,未來還有無限的可能。身...
    奈何歌閱讀 790評論 1 4
  • 最近在用手機看一些電子書,本來對自己的理解能力很是認可,這兩周看的一本書卻對自己的閱讀吸收水平產(chǎn)生了懷疑。 某公共...
    青兒姑娘閱讀 209評論 0 0

友情鏈接更多精彩內(nèi)容