博客
关于我
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/

你可能感兴趣的文章
mysql 转义字符用法_MySql 转义字符的使用说明
查看>>
mysql 输入密码秒退
查看>>
mysql 递归查找父节点_MySQL递归查询树状表的子节点、父节点具体实现
查看>>
mysql 里对root及普通用户赋权及更改密码的一些命令
查看>>
Mysql 重置自增列的开始序号
查看>>
MySQL 错误
查看>>
MySQL 面试,必须掌握的 8 大核心点
查看>>
MySQL 高可用性之keepalived+mysql双主
查看>>
MySql-2019-4-21-复习
查看>>
mysql-connector-java各种版本下载地址
查看>>
mysql-group_concat
查看>>
MySQL-redo日志
查看>>
MySQL-【1】配置
查看>>
MySQL-【4】基本操作
查看>>
Mysql-丢失更新
查看>>
Mysql-事务阻塞
查看>>
Mysql-存储引擎
查看>>
mysql-开启慢查询&所有操作记录日志
查看>>
MySQL-数据目录
查看>>
MySQL-数据页的结构
查看>>