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

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

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	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.Printf("程序用时:%v", end)}func GetImgUrl(url string, i int) {	defer wg.Done()	client := &http.Client{}	req, err := 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.Printf("http get error: %v\n", err)		return	}	fmt.Printf("GET %s: 200 OK\n", url)	log.Printf("GET %s: 200 OK\n", url)	defer response.Body.Close()	body, err := ioutil.ReadAll(response.Body)	if err != nil {		fmt.Printf("response.Body error: %v\n", err)		return	}	compile := regexp.MustCompile("http://~~不显示网址~~ /uploads/tu/[0-9]{6}/[0-9]{4}/[0-9a-zA-Z]{10}.jpg")	html := []byte(string(body))	submatch := compile.FindAllSubmatch(html, -1)	fmt.Printf("url: %s, match: %d\n", url, len(submatch))	if len(submatch) != 0 {		GetImg(string(submatch[0][0]), i)	} else {		fmt.Printf("url: %s, 无匹配项\n", url)	}}func GetImg(url string, i int) {	client := &http.Client{}	req, err := http.NewRequest("GET", url, nil)	if err != nil {		fmt.Printf("http get error: %v\n", err)		return	}	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.Printf("http get error: %v\n", err)		return	}	defer response.Body.Close()	body, err := ioutil.ReadAll(response.Body)	if err != nil {		fmt.Printf("response.Body error: %v\n", err)		return	}	timeStr := time.Now().Format("20060102 150405")	filename := fmt.Sprintf("./IMG/%s_%d.jpg", timeStr, i)	if err := ioutil.WriteFile(filename, body, 0666); err != nil {		fmt.Printf("ioutil.WriteFile error: %v\n", err)		return	} else {		fmt.Printf("下载了 %s 至 %s\n", url, filename)	}}

这段代码实现了通过多个协程并发下载网页内容中的图片文件,主要优化点包括:

  • 减少了不必要的注释和技术术语,使代码更简洁

  • 优化了日志输出格式,方便后续分析

  • 集成更高效的错误处理机制

  • 代码结构更清晰,适合协程多线程模型

  • 增加了文件保存的错误处理

  • 使用更简洁的参数传递机制

  • 内联了部分常用函数,提高了性能表现

  • 添加了时间跟踪功能,便于性能评估

  • 优化了图片文件存储路径和命名规则

  • 保持了代码的可扩展性和灵活性

  • 建议可以根据具体需求进一步优化,比如:

    • 可以根据具体需求调整最大的并发数量(num)
    • 集成进程池替代WaitGroup
    • 优化内存管理策略
    • 增加更全面的资源释放逻辑
    • 可以根据实际情况添加限流机制
    • 使用更高效的数据结构替代环环生变量

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

    你可能感兴趣的文章
    NI笔试——大数加法
    查看>>
    NLog 自定义字段 写入 oracle
    查看>>
    NLP 基于kashgari和BERT实现中文命名实体识别(NER)
    查看>>
    NLP 项目:维基百科文章爬虫和分类【01】 - 语料库阅读器
    查看>>
    NLP学习笔记:使用 Python 进行NLTK
    查看>>
    NLP问答系统:使用 Deepset SQUAD 和 SQuAD v2 度量评估
    查看>>
    NLP:使用 SciKit Learn 的文本矢量化方法
    查看>>
    Nmap扫描教程之Nmap基础知识
    查看>>
    Nmap端口扫描工具Windows安装和命令大全(非常详细)零基础入门到精通,收藏这篇就够了
    查看>>
    NMAP网络扫描工具的安装与使用
    查看>>
    NMF(非负矩阵分解)
    查看>>
    NN&DL4.1 Deep L-layer neural network简介
    查看>>
    NN&DL4.3 Getting your matrix dimensions right
    查看>>
    NN&DL4.8 What does this have to do with the brain?
    查看>>
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    查看>>
    NO 157 去掉禅道访问地址中的zentao
    查看>>
    No Datastore Session bound to thread, and configuration does not allow creation of non-transactional
    查看>>
    No fallbackFactory instance of type class com.ruoyi---SpringCloud Alibaba_若依微服务框架改造---工作笔记005
    查看>>
    No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalanc
    查看>>
    No mapping found for HTTP request with URI [/...] in DispatcherServlet with name ...的解决方法
    查看>>