本文已参与「新人创作礼」活动,一起开启掘金创作之路
我们可以先在文档先了解一下
go-colly
c.OnRequest(func(r *colly.Request) {
fmt.Println("Visiting", r.URL)
})//请求之前调用
c.OnError(func(_ *colly.Response, err error) {
log.Println("Something went wrong:", err)
})//请求期间发生错误调用
c.OnResponseHeaders(func(r *colly.Response) {
fmt.Println("Visited", r.Request.URL)
})//在收到响应头后调用
c.OnResponse(func(r *colly.Response) {
fmt.Println("Visited", r.Request.URL)
})//收到恢回复后调用
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
e.Request.Visit(e.Attr("href"))
})//收到的是html,之后调用
c.OnHTML("tr td:nth-of-type(1)", func(e *colly.HTMLElement) {
fmt.Println("First column of a table row:", e.Text)
})
c.OnXML("//h1", func(e *colly.XMLElement) {
fmt.Println(e.Text)
})//收到的是xml之后调用
c.OnScraped(func(r *colly.Response) {
fmt.Println("Finished", r.Request.URL)
})//回调之后调用
通过我们自己写的回调函数,当请求之前或接收之后等其他情况会调用函数
常用函数
c.Visit(url)//你要访问的url
c.OnHTML("匹配",func())
//onhtml()函数是返回html之后才调用的函数。
//通过第一个参数的匹配,如果返回的html中没有匹配到,则不会调用此回调函数。
//在c.OnHTML()中,如果再次使用c.Visit(),则会进行递归调用,再次使用c.OnHTML()。
c.OnHTML("*",func())如果,筛选条件变为*,通配符,则无论返回什么样的html,都会调用此回调函数
//所以,如果需要递归调用,则不能使用通配符
colly.MaxDepth()//设置最深递归层数
colly.AllowURLRevisit()//有时,爬虫需要重复爬取,如果不调用此方法,在第二次访问同一个url时,会报错
c.AllowURLRevisit=true//用处同上
c.AllowedDomains=//传递一个字符串的数组,如果设置此参数,则只能访问此参数里面的url,如果为空,则不会拦截
c.
入门案例
package main
import (
"flag"
"fmt"
"github.com/gocolly/colly"
"time"
)
type Desc struct {
ID int ` gorm:"primary_key;auto_increment"`
Title string
ViewNum string
}
func main() {
Csdn_views(100,"https://blog.csdn.net/Xiang_lhh")
}
func Csdn_views(num int , url string){
// Instantiate default collector
c := colly.NewCollector(//初始化colly
)
c.AllowURLRevisit=true//允许重复访问链接
c.OnHTML("div.navList-box", func(e *colly.HTMLElement) {//回调函数,查找每篇文章的子链接
e.ForEach("article.blog-list-box", func(i int, element *colly.HTMLElement) {
//遍历每个article标签
http_articleid:=element.ChildAttr("a","href")//得到标签属性
c.Visit(http_articleid)//递归访问子链接
time.Sleep(time.Second)//间隔一秒
})
})
c.OnHTML("div.article-header-box", func(e *colly.HTMLElement) {//自动匹配每篇文章的html
dom:=e.DOM//返回DOM对象
title:=dom.Find("h1.title-article").Text()//找到文章标题
view_num:=dom.Find("span.read-count").Text()//找到每篇文章的访问量
//注意colly为递归调用,不会重复刷新文章列表的页面,如果从文章列表中获取访问量,则访问量不会改变
fmt.Println("访问成功","标题:",title,"阅读量:",view_num)
})
c.OnError(func(response *colly.Response, err error) {
fmt.Println("错误",err,response)//如果出错,进行输出
})
// Before making a request print "Visiting ..."
c.OnRequest(func(r *colly.Request) {//访问之前
fmt.Println("Visiting", r.URL.String())
})
// Start scraping on https://hackerspaces.org
total:=1//访问次数
for total<=num{
fmt.Println("第",total,"次刷博客")
fmt.Println("等待三十秒钟自动开启...")
time.Sleep(time.Second*30)//每刷全部博客一次,自动间隔三十秒
err:=c.Visit(url)
if err !=nil{
fmt.Println("出现错误",err)
}
total++
}
}