欢迎光临
我们一直在努力

go语言学习例子No.20-多页面并发爬虫

按这个例子来,只要改engine.go就好了

上次用waitgroup来并发感觉很慢,完全没有并发的效果。。。

下面用channel来并发,嗖的一下,超级快!!!

参考:https://chai2010.gitbooks.io/advanced-go-programming-book/content/ch1-basic/ch1-06-goroutine.html

engine.go改如下

package engine

import (
	"fmt"
	"log"
	"runtime"
	"time"

	"crawler0.8/fetcher"
	"crawler0.8/parser"
)

func Run(seed parser.Request) { //参数是一个种子
	var requests []parser.Request     //新建一个队列接收种子
	requests = append(requests, seed) //接收参数传来的第一个种子

	runtime.GOMAXPROCS(runtime.NumCPU())
	jobChan := make(chan *parser.Request, 128)         //创建job通道来存放Request
	resultChan := make(chan *parser.ParserResult, 128) //创建result通道来存放ParserResult
	jobChan <- &seed                                   //发送第一个Request
	start := time.Now()
	count := 0
	createWork(64, jobChan, resultChan)             //创建工作池
	go func(resultchan chan *parser.ParserResult) { // 开个打印ParserResult的协程
		for result := range resultchan {
			requests = append(requests, result.Requests...) //这里可以获取到很多url加到队列中
			for _, item := range result.Items {
				fmt.Printf("%s \n", item) //打印队列里的项目
			}
			count = count + 1
			fmt.Printf("第%d个页面, 获取到%d条信息, time:%.2fs\n", count, len(result.Items), time.Since(start).Seconds())
		}

	}(resultChan)
	for {
		if len(requests) > 0 { //如果种子不位0
			r := requests[0]        //取第一个种子
			requests = requests[1:] //截掉第一个种子
			jobChan <- &r
		}
		time.Sleep(1 * time.Millisecond) //否则等一会让协程加点request先

	}

}

func createWork(num int, jobChan chan *parser.Request, resultChan chan *parser.ParserResult) {
	// 根据开协程个数,去跑运行
	for i := 0; i < num; i++ {
		go func(jobChan chan *parser.Request, resultChan chan *parser.ParserResult) {
			for job := range jobChan {
				contents, err := fetcher.Fetch(job.Url) //开始爬取对应种子的页面
				if err != nil {
					log.Printf("Fetching %s error!", job.Url)
					continue //如果获取失败就继续下一个种子
				}
				parserResult := job.ParserFunc(contents) //队列结构的函数提取结果
				//运算结果扔到管道
				resultChan <- &parserResult
			}

		}(jobChan, resultChan)
	}

}
 收藏 (0) 打赏

您可以选择一种方式赞助本站

支付宝扫一扫赞助

微信钱包扫描赞助

未经允许不得转载:家里蹲的狐狸 » go语言学习例子No.20-多页面并发爬虫

分享到: 生成海报
avatar

热门文章

  • 评论 抢沙发

    • QQ号
    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址

    登录

    忘记密码 ?

    切换登录

    注册

    我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活