Golang 實(shí)戰(zhàn) -- 老師爬取器

學(xué)習(xí)Golang有一陣子了满葛,本文從一個(gè)有趣的切入點(diǎn)(男生感覺(jué)有趣吧)昌罩。開(kāi)始了一段Golang之路。

需求場(chǎng)景描述

我有一個(gè)叫威威的大兄弟饭冬,對(duì)于老師們渴慕已久使鹅,但是又不慎了解。所以我打算寫(xiě)一個(gè)爬蟲(chóng)昌抠,爬一點(diǎn)老師的圖片患朱,來(lái)慰藉一下這位大兄弟。
簡(jiǎn)單的來(lái)說(shuō)就是寫(xiě)一個(gè)爬蟲(chóng)炊苫,實(shí)戰(zhàn)一下Go裁厅。當(dāng)然我是初學(xué)者,里面涉及到的包我想細(xì)致的講解侨艾,若有不足之處還請(qǐng)指出执虹。

老師爬取器

思路是這樣的,找一個(gè)網(wǎng)站蒋畜,然后爬取其中的HTML下來(lái)声畏。里面有許多圖片的URL,然后下載圖片的URL至本地即大功告成姻成。

爬蟲(chóng)主體代碼

func checkError(err error) bool {
    if err != nil {
        fmt.Println(err)
        return false
    }
    return true
}

func CrawlingImageTags(url string, imageChan chan []string) {
    req, err := http.NewRequest("GET", url, nil)
    if !checkError(err) {
        return
    }
    
    client := http.DefaultClient
    res, err := client.Do(req)
    if !checkError(err) {
        return
    }

    if res.StatusCode == 200 {
        body := res.Body
        defer body.Close()
        
        bodyByte, _ := ioutil.ReadAll(body)
        resStr := string(bodyByte)

        reg, _ := regexp.Compile("<img .*>")
        imageTags := reg.FindAllString(resStr, -1)
        imageChan <- imageTags
    }
}

代碼解釋:

  • checkError方法插龄,檢查err。
  • CrawlingImageTags方法科展,爬取HTML頁(yè)面均牢,并通過(guò)正則取出其中的Image標(biāo)簽。
  • 第一步 創(chuàng)建請(qǐng)求: http.NewRequest("GET", url, nil)才睹,NewRequest使用指定的方法徘跪、網(wǎng)址和可選的主題創(chuàng)建并返回一個(gè)新的*Request。
  • 第二步 發(fā)送請(qǐng)求:
  • client := http.DefaultClient獲取一個(gè)默認(rèn)的HTTP客戶端琅攘。
  • res, err := client.Do(req)垮庐,Do方法發(fā)送請(qǐng)求,返回HTTP回復(fù)坞琴。它會(huì)遵守客戶端c設(shè)置的策略哨查。這里這個(gè)Do請(qǐng)求是一個(gè)同步請(qǐng)求,也就是這個(gè)請(qǐng)求不返回剧辐,改Gorountine就會(huì)卡在這條語(yǔ)句上寒亥。
  • 第三步 獲取HTTP請(qǐng)求Body:
  • 注意的是要在defer中將body close掉邮府,原因參考link
  • 將io.Reader對(duì)象轉(zhuǎn)變成[]byte --> bodyByte, _ := ioutil.ReadAll(body)
  • 第四步 正則匹配。
  • 最好將得到的ImageTags的Slice放入Channel中溉奕,因?yàn)檫@里我們要開(kāi)多個(gè)Gorountine去爬取褂傀。

下載圖片

func getImageByUrl(url string) {
    reg, err := regexp.Compile("/.*jpg")
    if checkError(err) {
        return
    }
    image := host + reg.FindString(url)

    imageRequest, err := http.Get(image)
    if checkError(err) {
        return
    }

    data, err := ioutil.ReadAll(imageRequest.Body)
    defer imageRequest.Body.Close()
    if checkError(err) {
        return
    }

    path := strings.Split(image, "/")
    var name string
    if len(path) > 1 {
        name = "image/" + path[len(path)-1]
    }

    os.Mkdir("image", os.ModeType)
    out, err := os.Create(name)

    if checkError(err) {
        return
    }
    io.Copy(out, bytes.NewReader(data))
}

func getImageBySlice(imageSlice []string) {
    fmt.Println("back")
    for _, value := range imageSlice {
        getImageByUrl(value)
    }
}

代碼解釋:

  • 第一步:正則匹配挑出.jpg的URL地址,并拼接上host加勤。
  • 第二步:Get向指定的URL發(fā)出一個(gè)GET請(qǐng)求仙辟,如果回應(yīng)的狀態(tài)碼如下,Get會(huì)在調(diào)用c.CheckRedirect后執(zhí)行重定向 --> imageRequest, err := http.Get(image)
  • 第三步:確定image的名字胸竞,創(chuàng)建文件夾目錄
  • 第四步:創(chuàng)建一個(gè)空文件欺嗤,Create方法。doc
  • 最后拷貝數(shù)據(jù)卫枝,寫(xiě)入空文件。doc

最后是main方法

const url string = "http://www.ttpaihang.com/vote/rank.php?voteid=1089&page="
const host string = "http://www.ttpaihang.com"

func main() {
    runtime.GOMAXPROCS(4)
    i := 0
    for {
        i++
        imageChan := make(chan []string, 10)
        go CrawlingImageTags(url+strconv.Itoa(i), imageChan)
        go getImageBySlice(<-imageChan)
    }
}
  • 設(shè)置多核并行(并行于Gorotine并發(fā)有本質(zhì)區(qū)別)
  • 開(kāi)啟多個(gè)Gorotine并行下載讹挎。

總結(jié)

這里是從一個(gè)奇葩的切入點(diǎn)校赤,熟悉一下 CHannel和Gorotine的使用場(chǎng)景以及一些官方標(biāo)準(zhǔn)包的API熟悉。
希望能在Go的路上越走越遠(yuǎn)筒溃。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末马篮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子怜奖,更是在濱河造成了極大的恐慌浑测,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歪玲,死亡現(xiàn)場(chǎng)離奇詭異迁央,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)滥崩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門岖圈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人钙皮,你說(shuō)我怎么就攤上這事蜂科。” “怎么了短条?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵导匣,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我茸时,道長(zhǎng)贡定,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任屹蚊,我火速辦了婚禮厕氨,結(jié)果婚禮上进每,老公的妹妹穿的比我還像新娘。我一直安慰自己命斧,他們只是感情好田晚,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著国葬,像睡著了一般贤徒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汇四,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天接奈,我揣著相機(jī)與錄音,去河邊找鬼通孽。 笑死序宦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的背苦。 我是一名探鬼主播互捌,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼行剂!你這毒婦竟也來(lái)了秕噪?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤厚宰,失蹤者是張志新(化名)和其女友劉穎腌巾,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體铲觉,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡澈蝙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了备燃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碉克。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖并齐,靈堂內(nèi)的尸體忽然破棺而出漏麦,到底是詐尸還是另有隱情,我是刑警寧澤况褪,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布撕贞,位于F島的核電站,受9級(jí)特大地震影響测垛,放射性物質(zhì)發(fā)生泄漏捏膨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望号涯。 院中可真熱鬧目胡,春花似錦、人聲如沸链快。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)域蜗。三九已至巨双,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間霉祸,已是汗流浹背筑累。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留丝蹭,地道東北人慢宗。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像奔穿,于是被迫代替她去往敵國(guó)和親婆廊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容