Golang 实战 -- 老师爬取器

2017-01-06  本文已影响607人  David_Cap

学习Golang有一阵子了,本文从一个有趣的切入点(男生感觉有趣吧)。开始了一段Golang之路。

需求场景描述

我有一个叫威威的大兄弟,对于老师们渴慕已久,但是又不慎了解。所以我打算写一个爬虫,爬一点老师的图片,来慰藉一下这位大兄弟。
简单的来说就是写一个爬虫,实战一下Go。当然我是初学者,里面涉及到的包我想细致的讲解,若有不足之处还请指出。

老师爬取器

思路是这样的,找一个网站,然后爬取其中的HTML下来。里面有许多图片的URL,然后下载图片的URL至本地即大功告成。

爬虫主体代码

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
    }
}

代码解释:

下载图片

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)
    }
}

代码解释:

最后是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)
    }
}

总结

这里是从一个奇葩的切入点,熟悉一下 CHannel和Gorotine的使用场景以及一些官方标准包的API熟悉。
希望能在Go的路上越走越远。

上一篇 下一篇

猜你喜欢

热点阅读