网络爬虫——GO

2023-05-16

这里写目录标题

  • 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中广泛使用),来控制收集作业或获取信息,回调函数的调用顺序如下:

  1. OnRequest 在发起请求前被调用
  2. OnError 请求过程中如果发生错误被调用
  3. OnResponse 收到回复后被调用
  4. OnHTML 在OnResponse之后被调用,如果收到的内容是HTML
  5. 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 class="hotnews" 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 class="hotnews" 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选择器:有相邻就有兄弟,兄弟选择器就不一定要求相邻了,只要他们共有一个父元素就可以。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

网络爬虫——GO 的相关文章

  • macOS怎样备份?备份Mac文件的最佳方法

    备份macOS绝不是一个坏主意 xff0c 您的机器可能会损坏 xff0c 故障或变得更糟 无论出现什么问题 xff0c 备份都可以帮助您恢复正常工作 如何使用Time Machine和iCloud备份Mac 要使用Time Machine
  • Office 2019 for Mac激活失败,显示未找到许可证怎么办?

    无法激活office 2019 xff1f office 2019激活后提示找不到许可证 xff1f 今日小编找到一个解决办法 xff1a 原来是在启动程序中注册了office的授权系统监控程序 com microsoft office l
  • Mac 外接显示器色彩不正常解决方案

    使用 MacBook和MacMini使用外接第三方非 Apple 认证的显示器会有色彩问题 xff0c 可能是显示器颜色整体发灰 xff0c 也有可能绿色特别绿 这是因为Apple封闭的系统识别的显示器较少 xff0c 第三方厂商也未很好的
  • mybatis-xml配置

    xff08 一 xff09 先配置datasource properties配置文件 xff1a xff08 此步可省略 xff09 jdbc driver 61 com mysql jdbc Driver jdbc url 61 jdbc
  • ArchiCAD 24 Mac版3D建筑模型设计和分析软件新功能介绍

    ArchiCAD 24 Mac破解版全新上线 xff0c 有哪些新增功能 xff1f 小编给大家带来了这篇ArchiCAD 24 Mac版3D建筑模型设计和分析软件新功能介绍的文章 xff0c 希望可以帮到你 设计 创建集成模型 使用Arc
  • MacBook不断重启的 5 个原因以及如何解决此问题

    您的 Mac 是否突然无故重启 xff1f 您外出回来时 xff0c 突然发现您的 Mac 正在神秘地关闭并重新启动 xff0c 这非常令人生气 如果重新启动问题变得更加严重 xff0c 您的 MacBook可能根本无法使用 小编将为您带来
  • 如何使用Super Vectorizer在Mac上快速矢量化图像?

    如何在 Mac 上将 PDF 转换为SVG矢量 xff1f 有需要的朋友快来跟小编看看具体做法吧 xff01 步骤 1 xff1a 在 Mac 上打开 Super Image Vectorizer 将图像文件导入 Super Vectori
  • Mac电脑怎么使用ping命令?

    电脑出问题了 xff0c 上不了网 xff0c 想排查下电脑的问题出在哪儿就需要用到ping xff0c 但是如果是Mac电脑该如何ping呢 xff1f 其实在Mac 自带的 终端 中使用ping命令 xff0c 下面小编教你如何在Mac
  • 安装VMware Workstation Pro 16 教程,Ubuntu 18 桌面版安装教程

    目录 1 VMware Workstation 16 Pro 安装教程 2 Ubuntu 18 桌面版安装教程 1 VMware Workstation 16 Pro 安装教程 1 第一步 xff1a 到官网进行下载软件 xff0c 下载
  • STM32 创建LED工程,点亮LED

    容忍5V电压 FT 61 FIve Tolerate 允许5V 寄存器就是特殊的存储器 上拉输入和下拉输入 如果输入啥都不接 xff0c IO口输入电平极容易受外部电平干扰 xff0c 加上拉电阻就是为了保护输入引脚的电平 为了避免引脚悬空
  • C语言枚举使用技巧

    什么是C语言枚举 C语言枚举是一种用户自定义数据类型 xff0c 它允许程序员定义一个变量 xff0c 并将其限制为一组预定义的常量 这些常量被称为 枚举值 xff0c 并且可以通过名称进行引用 在C语言中 xff0c 枚举值是整数类型 x
  • 关于win10系统打开VMware虚拟机蓝屏的解决方案

    先说结论 xff1a 不要急着更改系统配置甚至重装系统 xff0c 首先检查自己的VMware版本 xff0c 如果为16 1或以前 xff0c 请将原先的版本升级为VMware17 0版本 xff01 xff01 xff01 本人当前电脑
  • 洛谷P1025

    这道题类似于把n个苹果放到k个盘子里且不能空盘子的问题 递归 xff08 dfs xff09 做法 include lt bits stdc 43 43 h gt define LL long long using namespace st
  • windows权限维持之shift后门

    原理 xff1a 沾滞键的目的是为了帮助那些按键有困难的人设计的 xff0c 在Windows系统下连续按5次shift键后 xff0c 系统就会执行C Windows System32下的sethc exe xff0c 也就是启用了沾滞键
  • PostgreSQL数据库smallint、bigint转到Oracle,要用什么类型替代? 是number么,那长度分别是多少?...

    个人意见 xff0c 仅供参考 xff1a smallint是有符号或无符号2字节的整数 xff0c 范围是0 xff5e 65 536 xff0c 5位整数 bigint是有符号或无符号8字节的整数 xff0c 范围是0 xff5e 18
  • 网络安全计算机基础

    计算机网络概念 xff1a 实际上是将分布在不同地理位置 xff0c 且具有独立功能的计算机 通过通信链路以及通信设备 xff0c 在网络操作系统 xff0c 网络管理软件及网络通信协议的管理和协调下实现信息传输与资源共享形成的计算机系统
  • ImportError:No module named ‘PIL‘

    运行时报错 xff1a ImportError No module named 39 PIL 原因是缺失一个pillow的数据包 xff0c 不能直接 pip install PIL xff0c 会提示找不到这个安装包 xff0c 需使用如
  • c++中#与##的作用

    1 c 43 43 中 用于把转换成字符串 define T A A 没有使用 using namespace std int main cout lt lt 34 T 2 34 lt lt T 2 lt lt endl cout lt l
  • 人工智能实验——八数码难题

    人工智能实验 八数码难题 人工智能实验 八数码难题 人工智能实验 八数码难题八数码难题简介八数码难题所用到的算法简介代码实现解释运行结果显示代码附件程序可视化 八数码难题简介 八数码问题指的是定义一个3 times 3的格子 xff0c 然
  • idea报错unable to reload maven project

    文章目录 前言一 问题状况二 解决步骤三 卸载maven仓库四 重新安装依赖总结 前言 今天从公司的svn中检出了一个老项目 xff0c 是jQuery 43 spring打造的项目 xff0c emmmm用eclipse编写 xff0c

随机推荐

  • VNC树莓派无法连接

    问题 xff1a 树莓派配置好VNC后 xff0c 第二次通过笔记本远程连接失败 xff0c 报错refused by the computer 解决方法 xff1a 在putty中输入IP地址登录树莓派 xff0c 输入vncserver
  • 经典LCA例题:P4180 [BJWC2010] 严格次小生成树

    Acwing xff1a 严格次小生成树 xff08 求两点间路径上最大边的权值 xff09 模板 洛谷 xff1a 严格次小生成树 求两点间路径上最大边的权值 xff0c 就不能通过前缀和了 xff0c 会丢失信息 每个结点存到其他结点的
  • linux下的压缩与解压缩

    由于计算机中的数据有些需要备份从而归档一个大文件中 下面介绍一下常用的linux压缩解压缩命令 1 关于tar的命令 参数解析 xff1a c 创建生成打包的文件 v 列出打包和解包的详细过程 xff0c 显示进度 f 指定文档的名称 xf
  • 关于fixed frame【odom】does not exist的问题

    在执行完roslaunch mbot description arbotix mbot with camera xacro launch后 xff0c 终端末端是否出现以下一段红色字体 xff0c 若有 xff0c 则此篇文章对你或许有用
  • Linux安装配置Tomcat

    1 下载Tomcat服务器 链接 xff1a https pan baidu com s 15wEXVJWdUUuXX1xRnXylUQ 提取码 xff1a 1234 官网下载 xff1a Apache Tomcat Apache Tomc
  • Oracle类型number与PG类型numeric对比和转换策略

    Oracle 11g number 任意精度数字类型 http docs oracle com cd B28359 01 server 111 b28318 datatype htm CNCPT313 存储数据的范围 正数 xff1a 1
  • 强制关闭linux进程

    问题 xff1a 卡住 xff0c 鼠标可以移动但点击无反应 xff0c 键盘可用 方法 xff1a xff08 1 xff09 Ctrl 43 Alt 43 T 打开终端 xff0c 输入top xff0c 显示的全是现在系统的进程 xf
  • 【计算机系统遇到的问题】win11权限开启方法——相机、麦克风等权限——“其中一些设置由你组织管理”

    win11更新后 xff0c 想必大家应该会出现跟我一样的问题 无法开启权限 xff0c 不知道在哪开启权限 我是在下午跟我老爸视频电话的时候发现这个问题的 xff0c 点击开摄像头 xff0c 但是我这边跟老爸那边却没有我的画面 xff0
  • gitlab安装部署

    本教程使用centos7 6 首先安装依赖包 yum install y curl policycoreutils python openssh server 如下提示相关依赖安装完成 安装步骤如下 xff1a 1 使用官方脚本添加yum源
  • 用51单片机中断控制LED灯亮灭

    用51单片机中断控制LED灯亮灭 span class token macro property span class token directive keyword include span span class token string
  • HDFS

    xff08 一 xff09 HDFS简介及其基本概念 HDFS xff08 Hadoop Distributed File System xff09 是hadoop生态系统的一个重要组成部分 xff0c 是hadoop中的的存储组件 xff
  • 如何在服务器用docker搭建Redis集群

    用docker部署Redis集群 这里用的是分片 43 高可用 43 负载均衡 xff0c 三主三从 第一步创建网卡 span class token comment 创建网卡 span span class token function
  • P1825 [USACO11OPEN]Corn Maze S——bfs

    USACO11OPEN Corn Maze S 题面翻译 奶牛们去一个 N M N times M N M 玉米迷宫 xff0c 2
  • 7-57 租用游艇问题——dp

    长江游艇俱乐部在长江上设置了n个游艇出租站1 xff0c 2 xff0c xff0c n 游客可在这些游艇出租站租用游艇 xff0c 并在下游的任何一个游艇出租站归还游艇 游艇出租站i到游艇出租站j之间的租金为r i j 1 lt 61 i
  • 三种接口实现增删改查

    目录 ArrayListHashSetHashMap ArrayList ArrayList 实现增删改查 span class token keyword package span span class token namespace t
  • 旗帜软件工作室2021年年度交接会议总结

    只有时间的消逝 xff0c 才使我们注意到时间 在小组的一年时间过的飞快 xff0c 在这一年里我们的心智品性和专业能力都经历了充分了磨练 和一年前的我们相比 xff0c 如今的我们更加成熟稳重 xff0c 不再心浮气躁 xff1b 在自己
  • nested exception is org.springframework.beans.factory.BeanCreationException: 不能注入对象 创建对象失败 spring...

    出现错误的背景 在使用Spring 43 SpringMVC 43 Mybatis SSM集成框架时 xff0c 服务器启动就会报错 错误根源 XML配置错误 解决方案 第一步 查找springmvc xml 配置文件中 是否添加了扫描注解
  • 算法练习——(2)逢7过

    1 中国朋友们聚会时喜欢玩 34 逢7过 34 的游戏 xff0c 老外有个同样的游戏 xff0c FlipFlop xff0c 它从1计数到100 xff0c 顺序输出 当遇到3的倍数就要说 Flip xff0c 遇到5的倍数就要说 Fl
  • beego的安装和简单使用

    beego的安装和使用 beego安装升级 beebee工具的安装 使用beebee newbee apibee runbee packbee version beego beego 是免费 开源的软件 xff0c beego 源代码目前托
  • 网络爬虫——GO

    这里写目录标题 go colly网络爬虫框架goquery HTML解析goquery主要的结构怎么使用goquery常用选择器 go colly网络爬虫框架 go colly是用Go实现的网络爬虫框架 go colly快速优雅 xff0c