Go语言学习之Go爬虫爬取图片信息

在Golang学习过程中,想到以往学习过的语言可以做爬虫,突发奇想,也用Go做了一个爬虫来爬取图片,以做困乏之时消遣作乐,话不多言,先上代码

package main

import (
	"fmt"
	"log"
	"strconv"
	"github.com/PuerkitoBio/goquery" // 解析html
	//"io/ioutil"
	"net/http"
	"os"
	"github.com/satori/go.uuid"    // 生成图片文件名
	"io/ioutil"
)

func getAllUrls() []string {

	var urls []string
	var url string
	for i := 0; i < 2; i++ {
		url = "http://www.meizitu.com/a/more_" + strconv.Itoa(i+1) + ".html"     //网址信息
		urls = append(urls, url)
	}
	return urls
}

func parseHtml(url string)  {
	doc, err := goquery.NewDocument(url)      //获取将要爬取的html文档信息
	if err != nil {
		log.Fatal(err)
	}
	p:=make(chan string)   //新开管道
	doc.Find(".pic > a > img").Each(func(i int, s *goquery.Selection) {    //遍历整个文档

		img_url, _ := s.Attr("src")
		// 启动协程下载图片

		go download(img_url,p)        //将管道传入download函数
		fmt.Println("src = "+ <-p+"图片爬取完毕")
	})

}

// 下载图片
func download(img_url string,p chan string)  {
	uid, _ := uuid.NewV4()               //随机生成四段文件名
	file_name := uid.String() + ".jpg"
	fmt.Println(file_name)
	f, err := os.Create(file_name)
	if err != nil{
		log.Panic("文件创建失败")
	}
	defer f.Close()       //结束关闭文件

	resp, err := http.Get(img_url)
	if err != nil{
		fmt.Println("http.get err",err)
	}

	body,err1 := ioutil.ReadAll(resp.Body)
	if err1 != nil{
		fmt.Println("读取数据失败")
	}
	defer resp.Body.Close()     //结束关闭
	f.Write(body)
	p <- file_name    //将文件名传入管道内

}

func main()  {
	urls := getAllUrls()
	for _, url := range urls {
		parseHtml(url)
	}
}

仅仅70来行代码,实现了一个并发高效的爬虫,我想这就是Go迷人之处吧

 

 首先:明确爬取的网址信息,我这里的网址信息如下

http://www.meizitu.com/a/more_" + strconv.Itoa(i+1) + ".html

然后:明确爬取图片的标识,一般图片为src,通过正则表达式或者goquery来解析html,我这里使用的goquery,只用git一下就可以使用,如下

go git  github.com/PuerkitoBio/goquery          go git github.com/satori/go.uuid

我这里文件名是随机生成的四段+.jpg构成

一个重要的点:管道的使用,之前的协程没有加上管道,总是发现图片信息爬取不完整,或少或空白,加上管道进行管理之后,发现协程就不会再出错,完美!因此管道也是Go的一个精髓所在。

本人所属Go学习小白,喜欢将所学之路放到网络之中与学者共知,有何理解不正确之处望大佬告知,谢谢!

 

你可能感兴趣的:(懵懂的代码狗)