colly框架学习(一)
1、项目初始化
-
新建项目文件夹
mkdir CollyStudy
-
项目初始化
cd CollyStudy go mod init CollyStudy
2、安装colly
-
安装
go get -u github.com/gocolly/colly/...
-
官方文档
https://go-colly.org/docs/
3、抓取数据
-
目标网站
https://ssr1.scrape.center/
-
创建Collector
import ( "github.com/gocolly/colly" "github.com/gocolly/colly/extensions" ) c := colly.NewCollector(func(collector *colly.Collector) { extensions.RandomUserAgent(collector) //随机UA collector.Async = true //异步 }, colly.AllowedDomains("ssr1.scrape.center"), //爬取范围 )
-
回调
// 请求发送之前调用 c.OnRequest(func(request *colly.Request) { request.Headers.Set("key", "value") //请求头添加 request.URL.String() // 请求url fmt.Println("Visiting", request.URL.String()) }) //相应内容为html是调用 c.OnHTML("a[href]", func(e *colly.HTMLElement) { element.Request.URL.String() // 请求url e.Request.Visit(e.Attr("href")) })
-
完整代码
package main import ( "fmt" "github.com/PuerkitoBio/goquery" "github.com/gocolly/colly" "github.com/gocolly/colly/extensions" "strings" ) func main() { fmt.Println("start crawling") // 初始化采集器 c := colly.NewCollector(func(collector *colly.Collector) { extensions.RandomUserAgent(collector) collector.Async = true }, colly.AllowedDomains("ssr1.scrape.center"), ) // 解析列表页 // 第一个参数为goquery语法 class属性为el-card__body的div c.OnHTML("div.el-card__body", func(element *colly.HTMLElement) { element.DOM.Each(func(i int, selection *goquery.Selection) { // each语法循环遍历div下的每一个元素, // 在每一个元素下面(子孙标签都算)寻找a标签,并提取href属性 link := selection.Find("a").Eq(0).AttrOr("href", "") fmt.Printf("link->%s\n", link) // AbsoluteURL为url绝对路径,自动补全 c.Visit(element.Request.AbsoluteURL(link)) }) }) // 详情页解析,内容在id为detail的div下 c.OnHTML("#detail", func(element *colly.HTMLElement) { // 获取第一个div,下标从0开始 firstDiv := element.DOM.Find("div").Eq(0) // div class属性如果不只一个,分别用写出,不需要分割符,连着写 info := firstDiv.Find("div.p-h.el-col.el-col-24.el-col-xs-16.el-col-sm-12") // .First().Text()获取第一个h2的文本内容 movieName := strings.TrimSpace(info.Find("h2").First().Text()) fmt.Printf("电影名:%s\n", movieName) categoryStr := strings.TrimSpace(info.Find("div.categories>button>span").Text()) fmt.Printf("类别:%s\n", categoryStr) // >表示直接子标签 locationDurationRelease := info.Find("div.m-v-sm.info>span").Text() locationDuration := strings.Split(locationDurationRelease, "/") location := strings.TrimSpace(locationDuration[0]) fmt.Printf("地区:%s\n", location) durationRelease := strings.Split(locationDuration[1], "分钟") duration := strings.TrimSpace(durationRelease[0]) fmt.Printf("时长:%s\n", duration) release := strings.TrimSpace(durationRelease[1]) fmt.Printf("上映时间:%s\n", release) // .Next()表示选择紧邻下一个标签 secondDiv := firstDiv.Next().Find("div.director.el-col.el-col-4") directors := strings.TrimSpace(secondDiv.Find("p.name.text-center.m-b-none.m-t-xs").First().Text()) fmt.Printf("导演:%s", directors) }) c.OnRequest(func(request *colly.Request) { fmt.Println("Visiting", request.URL.String()) }) c.Visit("https://ssr1.scrape.center/") c.Wait() // 等待所有爬虫结束 }