gocolly-OnResponse的使用(3)
文章目录
- 介绍
- demo
介绍
- 本章节使用OnResponse进行返回网页数据
- 使用xpath定位数据;
- 推荐htmlquery
demo
package mainimport ("fmt""github.com/antchfx/htmlquery""github.com/gocolly/colly""github.com/gocolly/colly/extensions""gopkg.in/xmlpath.v2""log""os""strings""time"
)/*
请求执行之前调用- OnRequest
响应返回之后调用- OnResponse
监听执行 selector- OnHTML
监听执行 selector- OnXML
错误回调- OnError
完成抓取后执行,完成所有工作后执行- OnScraped
取消监听,参数为 selector 字符串- OnHTMLDetach
取消监听,参数为 selector 字符串- OnXMLDetach
*/func init() {// 日志配置// 指定输出日志的前缀log.SetPrefix("【UserCenter】")// Ldate:时间// Lshortfile:文件名+源代码/*const (Ldate = 1 << iota //日期示例: 2009/01/23Ltime //时间示例: 01:23:23Lmicroseconds //毫秒示例: 01:23:23.123123.Llongfile //绝对路径和行号: /a/b/c/d.go:23Lshortfile //文件和行号: d.go:23.LUTC //日期时间转为0时区的LstdFlags = Ldate | Ltime //Go提供的标准抬头信息)*/log.SetFlags(log.LstdFlags | log.Lshortfile)}// 声明结构体
type Session struct {session *colly.Collectorfile *os.File
}// 初始化
func (c *Session) Init() *colly.Collector {// 实例化默认收集器c.session = colly.NewCollector()// 仅访问域c.session.AllowedDomains = []string{"quotes.toscrape.com"}// 允许重复访问c.session.AllowURLRevisit = true// 表示抓取时异步的// c.session.Async = true// 模拟浏览器c.session.UserAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"// 随机UserAgentextensions.RandomUserAgent(c.session)// 限制采集规则/*在Colly里面非常方便控制并发度,只抓取符合某个(些)规则的URLScolly.LimitRule{DomainGlob: "*.douban.*", Parallelism: 5},表示限制只抓取域名是douban(域名后缀和二级域名不限制)的地址,当然还支持正则匹配某些符合的 URLSLimit方法中也限制了并发是5。为什么要控制并发度呢?因为抓取的瓶颈往往来自对方网站的抓取频率的限制,如果在一段时间内达到某个抓取频率很容易被封,所以我们要控制抓取的频率。另外为了不给对方网站带来额外的压力和资源消耗,也应该控制你的抓取机制。*/err := c.session.Limit(&colly.LimitRule{// Filter domains affected by this rule// 筛选受此规则影响的域DomainGlob: "quotes.toscrape.com/*",// Set a delay between requests to these domains// 设置对这些域的请求之间的延迟Delay: 1 * time.Second,// Add an additional random delay// 添加额外的随机延迟RandomDelay: 1 * time.Second,// 设置并发Parallelism: 5,})if err != nil {fmt.Println(err)}return c.session
}// 开始爬取
func (c *Session) Visit(url string) error {// 开始爬取 urlerr := c.session.Visit(url)if err != nil {fmt.Println(err)return err}return nil
}// 访问下一页
// OnHTML selector
func (c *Session) getNext2(page *string) error {// 调用回调函数,获取标签的属性c.session.OnHTML(".pager .next a", func(e *colly.HTMLElement) {// 获取属性值link := e.Attr("href")*page = link})// 错误回调var err1 error = nilc.session.OnError(func(_ *colly.Response, err error) {fmt.Println("Something went wrong:", err)err1 = err})if err1 != nil {fmt.Println(err1)return err1}// 完成抓取后执行,完成所有工作后执行// c.session.OnScraped(func(r *colly.Response) {// fmt.Println("Finished", r.Request.URL)// })return nil
}// htmlquery xpath 推荐
func (c *Session) getNext(page *string) error {// 完成抓取后执行,完成所有工作后执行// c.session.OnScraped(func(r *colly.Response) {// fmt.Println("Finished", r.Request.URL)// })// 收到响应后c.session.OnResponse(func(r *colly.Response) {doc, err := htmlquery.Parse(strings.NewReader(string(r.Body)))if err != nil {log.Fatal(err)}link := htmlquery.FindOne(doc, `//ul[@class="pager"]/li[@class="next"]/a/@href`)*page = htmlquery.InnerText(link)// fmt.Println(*page)})// 错误回调var err1 error = nilc.session.OnError(func(_ *colly.Response, err error) {fmt.Println("Something went wrong:", err)err1 = err})if err1 != nil {fmt.Println(err1)return err1}return nil
}// gopkg.in/xmlpath.v2 xpath
func (c *Session) getNext3(page *string) error {// 完成抓取后执行,完成所有工作后执行// c.session.OnScraped(func(r *colly.Response) {// fmt.Println("Finished", r.Request.URL)// })// 收到响应后c.session.OnResponse(func(r *colly.Response) {doc, err := xmlpath.ParseHTML(strings.NewReader(string(r.Body)))if err != nil {log.Fatal(err)}path := xmlpath.MustCompile(`//ul[@class="pager"]/li[@class="next"]/a/@href`)if link, ok := path.String(doc); ok {*page = link}})// 错误回调var err1 error = nilc.session.OnError(func(_ *colly.Response, err error) {fmt.Println("Something went wrong:", err)err1 = err})if err1 != nil {fmt.Println(err1)return err1}return nil
}// 解析页面 OnHTML
func (c *Session) getParse2() {// 在每个 a 标签 href 属性 调用回调函数c.session.OnHTML(".row .col-md-8 .quote", func(e *colly.HTMLElement) {// texttext := e.ChildText("span.text")// fmt.Println("text: ", text)// authorauthor := e.ChildText("span .author")// fmt.Println("author: ", author)// tagsvar tags []stringe.ForEach(".tags a", func(i int, e *colly.HTMLElement) {text := e.Texttags = append(tags, text)})// fmt.Println("tags: ", tags)// 保存c.save(text, author, tags)})// 收到响应后c.session.OnResponse(func(r *colly.Response) {if r.StatusCode != 200 {log.Println(r.StatusCode)return}})
}// 解析页面 htmlquery xpath
func (c *Session) getParse() {// 收到响应后c.session.OnResponse(func(r *colly.Response) {if r.StatusCode != 200 {log.Println(r.StatusCode)return}doc, err := htmlquery.Parse(strings.NewReader(string(r.Body)))if err != nil {log.Fatal(err)}quoteNodes := htmlquery.Find(doc, `//div[@class="row"]/div[@class="col-md-8"]/div[@class="quote"]`)for _, node := range quoteNodes {textNode := htmlquery.FindOne(node, `./span[@class="text"]/text()`)text := htmlquery.InnerText(textNode)authorNode := htmlquery.FindOne(node, `./span/small[@class="author"]/text()`)author := htmlquery.InnerText(authorNode)var tags []stringaNodes := htmlquery.Find(node, `./div[@class="tags"]/a`)for _, a := range aNodes {tagNode := htmlquery.FindOne(a, `./text()`)tag := htmlquery.InnerText(tagNode)tags = append(tags, tag)}fmt.Println(text)fmt.Println(author)fmt.Println(tags)// 保存c.save(text, author, tags)}})
}// 翻页
func (c *Session) NextPage() {// 访问地址url := "http://quotes.toscrape.com"baseUrl := "http://quotes.toscrape.com"page := ""for i := 0; i <= 2; i++ {fmt.Println("start url: ", url)// 解析页面c.getParse()// 获取下一页地址err1 := c.getNext(&page)if err1 != nil {break}err2 := c.Visit(url)if err2 != nil {break}url = baseUrl + page}}// 保存
func (c *Session) save(text string, author string, tags []string) {newTags := strings.Join(tags, " ")// fmt.Println(newTags)_, _ = c.file.Write([]byte(text + "\n"))_, _ = c.file.Write([]byte(author + "\n"))_, _ = c.file.Write([]byte(newTags + "\n"))_, _ = c.file.Write([]byte(strings.Repeat("*", 20)))_, _ = c.file.Write([]byte("\n\n"))
}func main() {s := &Session{}// 初始化s.Init()// 读写模式打开,写入追加s.file, _ = os.OpenFile("test.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0777)defer func() {if err := s.file.Close(); err != nil {fmt.Println(err)}}()// 翻页s.NextPage()// 采集等待结束s.session.Wait()fmt.Println("程序运行结束!")
}
gocolly-OnResponse的使用(3)相关推荐
- (golang)HTTP基本认证机制及使用gocolly登录爬取
内网有个网页用了HTTP基本认证机制,想用gocolly爬取,不知道怎么登录,只好研究HTTP基本认证机制 参考这里:https://www.jb51.net/article/89070.htm 下面 ...
- Golang 网络爬虫框架gocolly/colly
gocolly是Golang实现的网络爬虫框架,名列go版爬虫程序榜首. 安装 go get -u github.com/gocolly/colly/... 例子 import ( "fmt ...
- 非零基础自学Golang 第17章 HTTP编程(上) 17.3 爬虫框架gocolly 17.3.1 gocolly简介
非零基础自学Golang 文章目录 非零基础自学Golang 第17章 HTTP编程(上) 17.3 爬虫框架gocolly 17.3.1 gocolly简介 第17章 HTTP编程(上) 17.3 ...
- Golang 网络爬虫框架gocolly/colly 四
爬虫靠演技,表演得越像浏览器,抓取数据越容易,这是我多年爬虫经验的感悟.回顾下个人的爬虫经历,共分三个阶段:第一阶段,09年左右开始接触爬虫,那时由于项目需要,要访问各大国际社交网站,Facebook ...
- go-colly入门+案例
我们可以先在文档先了解一下 go-colly c.OnRequest(func(r *colly.Request) {fmt.Println("Visiting", r.URL) ...
- go-colly官方文档翻译(持续翻译中)
介绍 如何安装 煤灰只有一个前提,那就是Golang编程语言. 你可以使用他们的安装指南 https://golang.org/doc/install 在终端输入以下命令安装煤灰和回车. go get ...
- Golang网络爬虫框架gocolly/colly(三)
熟悉了<Golang 网络爬虫框架gocolly/colly 一>和<Golang 网络爬虫框架gocolly/colly 二>之后就可以在网络上爬取大部分数据了.本文接下来将 ...
- 安装 Go-Colly
1.go get -u github.com/gocolly/colly/ 2.执行完后看到如下报错 package github.com/gocolly/colly imports golang.o ...
- go 爬虫框架 - gocolly
colly 是 Go 实现的比较有名的一款爬虫框架,而且 Go 在高并发和分布式场景的优势也正是爬虫技术所需要的.它的主要特点是轻量.快速,设计非常优雅,并且分布式的支持也非常简单,易于扩展. 使用 ...
- Android --- Retrofit 之 Okhttp3 网络请求总是调用 onFailure 方法,而不调用 onResponse,报错 timeout。
今天在做 Android 项目的时候使用到了 okhttp3 的网络请求,由于我没有设置 ReadTimeout,指的是建立连接后从服务器读取到可用资源所用的时间.所以就会抛出异常(timeout), ...
最新文章
- 失业后跑摩的985高校硕士,被质疑学历、深“扒”论文...
- Mysql高级调优篇——前言简介
- 安装mysql5.7出现问题_转载---安装mysql5.7,遇到的问题
- iOS开发基础知识-多线程概念深入浅出
- 最长上升子序列(LIS)和最长公共子序列(LCS) 模板
- linux查看yum源信息,Linux系统配置163或sohu yum源
- (转)比较全的OA模板
- Detours使用方法,简单明了
- 第八章-分析句子结构
- golang库文件收集
- Allegro导出pdf的两种方式
- 技嘉显卡性能测试软件,显卡性能与超频:性能高于公版,超频潜力可圈可点
- 字符串函数的模拟实现
- 算法实践——数独的基本解法
- 实测搭建学法减分助手小程序系统源码
- 8.14. JSON Types
- 快速保存网页中所有图片的方法
- 【杂谈】 Listary自带的字典功能失效?没关系,让我们自己来改造它
- 2016计算机学科夏令营上机考试C:反反复复(字符串处理)
- 反弹Shell命令一键生成工具