网络爬虫——GO

网络爬虫——GO

    正在检查是否收录...

这里写目录标题

go-colly网络爬虫框架 goquery HTML解析 goquery主要的结构 怎么使用goquery 常用选择器

go-colly网络爬虫框架

go-colly是用Go实现的网络爬虫框架。go-colly快速优雅,在单核上每秒可以发起1K以上请求;以回调函数的形式提供了一组接口,可以实现任意类型的爬虫。

Colly 特性:
清晰的API 快速(单个内核上的请求数大于1k) 管理每个域的请求延迟和最大并发数 自动cookie 和会话处理
同步/异步/并行抓取 高速缓存 自动处理非Unicode的编码 支持Robots.txt 定制Agent信息 定制抓取频次**

下载安装第三方包:
go get -u github.com/gocolly/colly/…

在代码中导入包:

import "github.com/gocolly/colly" 

colly的主体是Collector对象,管理网络通信和负责在作业运行时执行附加的回调函数。使用colly需要先初始化Collector:

c := colly.NewCollector() 

NewCollector,是变参函数,参数类型为函数类型func(*Collector),主要是用来初始化一个&Collector{}对象。

而在Colly中有好些函数都返回这个函数类型func(*Collector),如UserAgent(us string)用来设置UA。所以,这里其实是一种初始化对象,设置对象属性的一种模式。相比使用方法(set方法)这种传统方式来初始设置对象属性,采用回调函数的形式在Go语言中更灵活更方便:

NewCollector(options ...func(*Collector)) *Collector UserAgent(ua string) func(*Collector) 

一旦得到一个colly对象,可以向colly附加各种不同类型的回调函数(回调函数在Colly中广泛使用),来控制收集作业或获取信息,回调函数的调用顺序如下:

OnRequest 在发起请求前被调用 OnError 请求过程中如果发生错误被调用 OnResponse 收到回复后被调用 OnHTML 在OnResponse之后被调用,如果收到的内容是HTML OnScraped 在OnHTML之后被调用

例子:

package main import ( "fmt" "github.com/gocolly/colly" ) func main() { // NewCollector(options ...func(*Collector)) *Collector // 声明初始化NewCollector对象时可以指定Agent,连接递归深度,URL过滤以及domain限制等 c := colly.NewCollector( //colly.AllowedDomains("news.baidu.com"), colly.UserAgent("Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.9.168 Version/11.50")) // 发出请求时附的回调 c.OnRequest(func(r *colly.Request) { // Request头部设定 r.Headers.Set("Host", "baidu.com") r.Headers.Set("Connection", "keep-alive") r.Headers.Set("Accept", "*/*") r.Headers.Set("Origin", "") r.Headers.Set("Referer", "http://www.baidu.com") r.Headers.Set("Accept-Encoding", "gzip, deflate") r.Headers.Set("Accept-Language", "zh-CN, zh;q=0.9") fmt.Println("Visiting", r.URL) }) // 对响应的HTML元素处理 c.OnHTML("title", func(e *colly.HTMLElement) { //e.Request.Visit(e.Attr("href")) fmt.Println("title:", e.Text) }) c.OnHTML("body", func(e *colly.HTMLElement) { // <div alog-group="focustop-hotnews"> 下所有的a解析 e.ForEach(".hotnews a", func(i int, el *colly.HTMLElement) { band := el.Attr("href") title := el.Text fmt.Printf("新闻 %d : %s - %s\n", i, title, band) // e.Request.Visit(band) }) }) // 发现并访问下一个连接 //c.OnHTML(`.next a[href]`, func(e *colly.HTMLElement) { // e.Request.Visit(e.Attr("href")) //}) // extract status code c.OnResponse(func(r *colly.Response) { fmt.Println("response received", r.StatusCode) // 设置context // fmt.Println(r.Ctx.Get("url")) }) // 对visit的线程数做限制,visit可以同时运行多个 c.Limit(&colly.LimitRule{ Parallelism: 2, //Delay: 5 * time.Second, }) c.Visit("http://news.baidu.com") } 

goquery HTML解析

colly框架可以快速发起请求,接收服务器响应。但如果我们需要分析返回的HTML代码,这时候仅仅使用colly就有点吃力。而goquery库是一个使用Go语言写成的HTML解析库,功能更加强大。

goquery将jQuery的语法和特性引入进来,所以可以更灵活地选择采集内容的数据项,就像jQuery那样的方式来操作DOM文档,使用起来非常的简便。

goquery主要的结构

type Document struct { *Selection Url *url.URL rootNode *html.Node } 

Document 嵌入了Selection 类型,因此,Document 可以直接使用 Selection 类型的方法。我们可以通过下面四种方式来初始化得到*Document对象。

func NewDocumentFromNode(root *html.Node) *Document func NewDocument(url string) (*Document, error) func NewDocumentFromReader(r io.Reader) (*Document, error) func NewDocumentFromResponse(res *http.Response) (*Document, error) 

Selection 是重要的一个结构体,解析中最重要,最核心的方法方法都由它提供。

type Selection struct { Nodes []*html.Node document *Document prevSel *Selection } 

怎么使用goquery

首先,要确定已经下载安装这个第三方包:
go get github.com/PuerkitoBio/goquery

接下来在代码中导入包:

import "github.com/PuerkitoBio/goquery" 

goquery可以直接发送url请求,获得响应后得到HTML代码。但goquery主要擅长于HTML代码分析,而colly在爬虫抓取管理调度上有优势,所以下面以colly作为爬虫框架,goquery作为HTML分析器,看看怎么抓取并分析页面内容:

package main import ( "bytes" "fmt" "log" "net/url" "time" "github.com/PuerkitoBio/goquery" "github.com/gocolly/colly" ) func main() { urlstr := "https://news.baidu.com" u, err := url.Parse(urlstr) if err != nil { log.Fatal(err) } c := colly.NewCollector() // 超时设定 c.SetRequestTimeout(100 * time.Second) // 指定Agent信息 c.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36" c.OnRequest(func(r *colly.Request) { // Request头部设定 r.Headers.Set("Host", u.Host) r.Headers.Set("Connection", "keep-alive") r.Headers.Set("Accept", "*/*") r.Headers.Set("Origin", u.Host) r.Headers.Set("Referer", urlstr) r.Headers.Set("Accept-Encoding", "gzip, deflate") r.Headers.Set("Accept-Language", "zh-CN, zh;q=0.9") }) c.OnHTML("title", func(e *colly.HTMLElement) { fmt.Println("title:", e.Text) }) c.OnResponse(func(resp *colly.Response) { fmt.Println("response received", resp.StatusCode) // goquery直接读取resp.Body的内容 htmlDoc, err := goquery.NewDocumentFromReader(bytes.NewReader(resp.Body)) // 读取url再传给goquery,访问url读取内容,此处不建议使用 // htmlDoc, err := goquery.NewDocument(resp.Request.URL.String()) if err != nil { log.Fatal(err) } // 找到抓取项 <div alog-group="focustop-hotnews"> 下所有的a解析 htmlDoc.Find(".hotnews a").Each(func(i int, s *goquery.Selection) { band, _ := s.Attr("href") title := s.Text() fmt.Printf("热点新闻 %d: %s - %s\n", i, title, band) c.Visit(band) }) }) c.OnError(func(resp *colly.Response, errHttp error) { err = errHttp }) err = c.Visit(urlstr) } 

常用选择器

HTML Element 元素的选择器 ID 选择器 Element ID 选择器 Find(element#id) Class选择器 Find(".class") 属性选择器 Find(“div[lang]“) 筛选含有lang属性的div元素 Find(“div[lang=zh]“) 筛选lang属性为zh的div元素 Find(“div[lang!=zh]“) 筛选lang属性不等于zh的div元素 Find(“div[lang¦=zh]“) 筛选lang属性为zh或者zh-开头的div元素 Find(“div[lang*=zh]“) 筛选lang属性包含zh这个字符串的div元素 Find(“div[lang~=zh]“) 筛选lang属性包含zh这个单词的div元素,单词以空格分开的 Find(“div[lang$=zh]“) 筛选lang属性以zh结尾的div元素,区分大小写 Find(“div[lang^=zh]“) 筛选lang属性以zh开头的div元素,区分大小写 parent>child选择器:如果我们想筛选出某个元素下符合条件的子元素,我们就可以使用子元素筛选器,它的语法为Find(“parent>child”),表示筛选parent这个父元素下,符合child这个条件的最直接(一级)的子元素。 prev+next相邻选择器:假设我们要筛选的元素没有规律,但是该元素的上一个元素有规律,我们就可以使用这种下一个相邻选择器来进行选择。 prev~next选择器:有相邻就有兄弟,兄弟选择器就不一定要求相邻了,只要他们共有一个父元素就可以。

htmlcodedocurlctogithubgitbaidurag网络爬虫windowscodingchromeapiapplemozillawebparseapp服务器rapbot代码分析自动处理
  • 本文作者:李琛
  • 本文链接: https://wapzz.net/post-536.html
  • 版权声明:本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。
本站部分内容来源于网络转载,仅供学习交流使用。如涉及版权问题,请及时联系我们,我们将第一时间处理。
文章很赞!支持一下吧 还没有人为TA充电
为TA充电
还没有人为TA充电
0
  • 支付宝打赏
    支付宝扫一扫
  • 微信打赏
    微信扫一扫
感谢支持
文章很赞!支持一下吧
关于作者
2.3W+
5
0
1
WAP站长官方

Stable Diffusion 本地部署教程 踩的一些坑

上一篇

AI 绘画Stable Diffusion 研究(三)sd模型种类介绍及安装使用详解

下一篇
  • 复制图片
按住ctrl可打开默认菜单