博客
关于我
go基础综合-goroutine实现网页爬虫
阅读量:605 次
发布时间:2019-03-12

本文共 2362 字,大约阅读时间需要 7 分钟。

涉及go的net/http包的使用,文件读写,log日志、正则匹配、go routine并发、协程同步。

package mainimport (	"fmt"	"net/http"	"io/ioutil"	"regexp"	"sync"	"log"	"time"	"os")var wg sync.WaitGroupfunc main() {   	log_f, err := os.OpenFile("down.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)	if err !=nil {   		log.Fatal(err)	}	defer log_f.Close()	log.SetOutput(log_f)	//记录用时	t := time.Now()	num := 20 //开启20个协程爬20个网页	wg.Add(num)	for i:=0; i<=num; i++ {   		url := fmt.Sprintf("https://~~不显示网址~~ /20140421192446_%d.htm", i+2)		fmt.Println(url)		log.Printf("GET %s\n", url)		go GetImgUrl(url, i)	}	wg.Wait()//主协程等待	end := time.Since(t)    fmt.Println("程序用时:", end)}func GetImgUrl(url string, i int) {   	defer wg.Done()	client := &http.Client{   }	req,_ := http.NewRequest("GET",url,nil)	req.Header.Add("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0")		response, err := client.Do(req)	if err != nil {   		fmt.Println("http get error ",err)		return 	}	fmt.Println(url, response.Status)	log.Println(url, response.Status)	defer response.Body.Close()	body, err := ioutil.ReadAll(response.Body)	if err != nil {   		fmt.Println("response.Body error")		return 	}	reg := "http://~~不显示网址~~ /uploads/tu/[0-9]{6}/[0-9]{4}/[0-9a-zA-Z]{10}.jpg"	compile := regexp.MustCompile(reg)	html  := []byte(string(body)) 	submatch := compile.FindAllSubmatch(html, -1)	fmt.Println("url:" , url, "match:", len(submatch))	if len(submatch) != 0 {   		GetImg(string(submatch[0][0]), i)	}else {   		fmt.Println("url:" , url, "null", len(submatch))	}}func GetImg(url string, i int) {   	client := &http.Client{   }	req,_ := http.NewRequest("GET",url,nil)	req.Header.Add("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0")	    response, err := client.Do(req)	if err != nil {   		fmt.Println("http get error ",err)		return 	}	defer response.Body.Close()	body, err := ioutil.ReadAll(response.Body)	if err != nil {   		fmt.Println("response.Body error")		return 	}	timeStr := time.Now().Format("2006-01-02 15:04:05")	filename := fmt.Sprintf("./IMG/%s_%d.jpg", timeStr, i)	//fmt.Println(filename)	err = ioutil.WriteFile(filename, body, 0666)	if err != nil {   		fmt.Println("ioutil.WriteFile error", err)		return 	}else {   		fmt.Println(url, " ok")	}}

转载地址:http://tynxz.baihongyu.com/

你可能感兴趣的文章
mt_rand
查看>>
mysql /*! 50100 ... */ 条件编译
查看>>
mudbox卸载/完美解决安装失败/如何彻底卸载清除干净mudbox各种残留注册表和文件的方法...
查看>>
mysql 1264_关于mysql 出现 1264 Out of range value for column 错误的解决办法
查看>>
mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
查看>>
mysql 5.6 修改端口_mysql5.6.24怎么修改端口号
查看>>
MySQL 8.0 恢复孤立文件每表ibd文件
查看>>
MySQL 8.0开始Group by不再排序
查看>>
mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
查看>>
multi swiper bug solution
查看>>
MySQL Binlog 日志监听与 Spring 集成实战
查看>>
MySQL binlog三种模式
查看>>
multi-angle cosine and sines
查看>>
Mysql Can't connect to MySQL server
查看>>
mysql case when 乱码_Mysql CASE WHEN 用法
查看>>
Multicast1
查看>>
MySQL Cluster 7.0.36 发布
查看>>
Multimodal Unsupervised Image-to-Image Translation多通道无监督图像翻译
查看>>
MySQL Cluster与MGR集群实战
查看>>
multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
查看>>