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

你可能感兴趣的文章
Netty工作笔记0057---Netty群聊系统服务端
查看>>
Netty工作笔记0058---Netty群聊系统客户端
查看>>
Netty工作笔记0059---Netty私聊实现思路
查看>>
Netty工作笔记0060---Netty心跳机制实例
查看>>
Netty工作笔记0060---Tcp长连接和短连接_Http长连接和短连接_UDP长连接和短连接
查看>>
Netty工作笔记0061---Netty心跳处理器编写
查看>>
Netty工作笔记0062---WebSocket长连接开发
查看>>
Netty工作笔记0063---WebSocket长连接开发2
查看>>
vue样式穿透 ::v-deep的具体使用
查看>>
Netty工作笔记0065---WebSocket长连接开发4
查看>>
Netty工作笔记0066---Netty核心模块内容梳理
查看>>
Vue基本使用---vue工作笔记0002
查看>>
Netty工作笔记0068---Protobuf机制简述
查看>>
Netty工作笔记0069---Protobuf使用案例
查看>>
Netty工作笔记0070---Protobuf使用案例Codec使用
查看>>
Netty工作笔记0071---Protobuf传输多种类型
查看>>
Netty工作笔记0072---Protobuf内容小结
查看>>
Netty工作笔记0073---Neety的出站和入站机制
查看>>
Netty工作笔记0074---handler链调用机制实例1
查看>>
Netty工作笔记0075---handler链调用机制实例1
查看>>