基于gathertool高并发抓取阳光高考招生简章

mange · · 1644 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

# golang爬虫高并发抓取阳光高考招生简章 ## 链接地址 > 一级页面 学校列表 https://gaokao.chsi.com.cn/zsgs/zhangcheng/listVerifedZszc--method-index,lb-1,start-0.dhtml >二级页 招生简章列表 https://gaokao.chsi.com.cn/zsgs/zhangcheng/listZszc--schId-5.dhtml > 三级页 招生章程内容 https://gaokao.chsi.com.cn/zsgs/zhangcheng/listVerifedZszc--infoId-2708104715,method-view,schId-5.dhtml ## 抓取流程 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210428211129548.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01hbl9nZQ==,size_16,color_FFFFFF,t_70#pic_center) ## 抓取框架 gathertool >框架地址: https://github.com/mangenotwork/gathertool 框架下载: go get github.com/mangenotwork/gathertool 介绍: 轻量级爬虫,接口测试,压力测试框架, 提高开发对应场景的golang程序。 框架文档: https://380949.baklib-free.com/ ## 实现 ```golang package main import ( "fmt" "log" "time" "github.com/PuerkitoBio/goquery" gt "github.com/mangenotwork/gathertool" ) var ( PG1Queue = gt.NewQueue() // 一级页面抓取任务队列 PG2Queue = gt.NewQueue() // 二级页面抓取任务队列 PG3Queue = gt.NewQueue() // 三级页面抓取任务队列 host = "127.0.0.1" port = 3306 user = "root" password = "root123" database = "spider" tableName = "yggk_zszc_1" ) func init(){ gt.NewMysqlDB(host, port, user, password, database) err := gt.MysqlDB.Conn() if err != nil{ log.Panic("数据库初始化失败") } //初始化表 gt.MysqlDB.NewTable(tableName, map[string]string{ "school_name": "varchar(30)", "zszcName" : "varchar(50)", "fbTime" : "varchar(30)", "url" : "varchar(200)", "content": "text", }) } // 全量抓取 func main(){ // 一共 29页 for p:=0; p<30;p++{ pg1 := "https://gaokao.chsi.com.cn/zsgs/zhangcheng/listVerifedZszc--method-index,lb-1,start-%d.dhtml" PG1Queue.Add(&gt.Task{ Url: fmt.Sprintf(pg1, p*100), }) } //并发执行一级页面 gt.StartJobGet(50,PG1Queue, gt.SucceedFunc(Pg1Succeed),//请求成功后执行的方法 gt.RetryFunc(Retry), gt.FailedFunc(Fail), ) log.Println(" 并发执行一级页面 完成") //并发执行二级页面 gt.StartJobGet(50,PG2Queue, gt.SucceedFunc(Pg2Succeed),//请求成功后执行的方法 gt.RetryFunc(Retry), gt.FailedFunc(Fail), ) log.Println(" 并发执行二级页面 完成") //并发执行三级页面 gt.StartJobGet(100,PG3Queue, gt.SucceedFunc(Pg3Succeed),//请求成功后执行的方法 gt.RetryFunc(Retry), gt.FailedFunc(Fail), ) log.Println(" 并发执行三级页面 完成") ////测试第二级页面 //c,_ := gt.Get("https://gaokao.chsi.com.cn/zsgs/zhangcheng/listZszc--schId-1.dhtml", // gt.SucceedFunc(Pg2Succeed)) //c.Do() //测试第三级页面 //for i:=0; i<100;i++{ // go func(){ // c,_ := gt.Get("https://gaokao.chsi.com.cn/zsgs/zhangcheng/listVerifedZszc--infoId-2697675279,method-view,schId-1.dhtml", // gt.SucceedFunc(Pg3Succeed)) // c.Do() // }() //} //time.Sleep(10*time.Second) } // 抓取第一级页面成功后 func Pg1Succeed(ctx *gt.Context){ html := string(ctx.RespBody) dom,err := gt.NewGoquery(html) if err != nil{ log.Println(err) return } result := dom.Find("table tbody") if len(result.Nodes) < 2{ log.Println("没有找到table") } result.Eq(1).Each(func(i int, tr *goquery.Selection){ tr.Find("td").Each(func(i int, td *goquery.Selection){ schoolName := td.Text() href,_ := td.Find("a").Attr("href") log.Println(schoolName, href) // 加入二级页面队列 PG2Queue.Add(&gt.Task{ Url: "https://gaokao.chsi.com.cn/" + href, Data: map[string]interface{}{ "school_name":schoolName, }, }) }) }) } // 抓取第二级页面成功后 func Pg2Succeed(ctx *gt.Context){ html := string(ctx.RespBody) dom,err := gt.NewGoquery(html) if err != nil{ log.Println(err) return } result := dom.Find(".zszcdel table tbody") //log.Println(result.Html()) result.Find("tr").Each(func(i int, tr *goquery.Selection){ td := tr.Find("td") zszcName := td.Eq(0).Text() href,_ := td.Eq(0).Find("a").Attr("href") fbTime := td.Eq(1).Text() log.Println(zszcName, href, fbTime) ctx.Task.Data["zszcName"] = zszcName ctx.Task.Data["fbTime"] = fbTime ctx.Task.Data["url"] = "https://gaokao.chsi.com.cn/" + href ctx.Task.Url = "https://gaokao.chsi.com.cn/" + href PG3Queue.Add(ctx.Task) }) } // 抓取第二级页面成功后 func Pg3Succeed(ctx *gt.Context){ html := string(ctx.RespBody) //log.Println(html) dom,err := gt.NewGoquery(html) if err != nil{ log.Println(err) return } content,err := dom.Find(".content").Html() log.Println(content, err) if err != nil || content == ""{ log.Println("还给队列") PG3Queue.Add(ctx.Task) } // 写入数据库 schoolName := gt.StringValue(ctx.Task.Data["school_name"]) // 转换成字符串 zszcName := gt.StringValue(ctx.Task.Data["zszcName"]) fbTime := gt.StringValue(ctx.Task.Data["fbTime"]) err = gt.MysqlDB.Insert(tableName, map[string]interface{}{ "school_name": gt.CleaningStr(schoolName), // 清理字符串前后空格和换行符等 "zszcName" : gt.CleaningStr(zszcName), "fbTime" : gt.CleaningStr(fbTime), "url" : ctx.Task.Data["url"], "content": content, }) log.Println(err) } func Retry(*gt.Context){ time.Sleep(2*time.Second) } func Fail(ctx *gt.Context){ log.Println(ctx.Err) } ``` ## 结果 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210428211522105.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01hbl9nZQ==,size_16,color_FFFFFF,t_70#pic_center)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1644 次点击  ∙  1 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传