当前位置: 首页 > news >正文

Golang爬虫封装

引言

爬虫是一种自动化地从网页中提取信息的程序,它在现代互联网的数据获取和分析中扮演着重要的角色。Golang作为一门强大的编程语言,也提供了丰富的工具和库来实现爬虫功能。在本文中,我们将探讨如何使用Golang来封装一个灵活、高效的爬虫程序。

1. Golang爬虫概述

在开始讨论封装爬虫之前,我们先来了解一下Golang中的爬虫概念和基本原理。爬虫通常由以下几个组件组成:

  • 网页下载器:负责从URL中下载网页内容。
  • 网页解析器:负责解析网页内容,提取所需的数据。
  • 数据存储器:负责将提取的数据存储到本地或者数据库中。

Golang提供了许多强大的库和工具来实现这些组件,如net/http库用于下载网页,goquery库用于解析HTML,database/sql库用于数据存储等。

2. 封装爬虫功能模块

为了提高代码的可读性和可维护性,我们将爬虫功能模块进行封装。以下是一个简单的爬虫封装示例:

package crawlerimport ("fmt""io/ioutil""net/http"
)type Crawler struct {
}func (c *Crawler) Download(url string) ([]byte, error) {resp, err := http.Get(url)if err != nil {return nil, err}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {return nil, err}return body, nil
}func (c *Crawler) Parse(body []byte) {// 解析网页内容// 提取所需的数据
}func (c *Crawler) Store(data string) {// 存储数据到本地或数据库
}func (c *Crawler) Run(url string) {body, err := c.Download(url)if err != nil {fmt.Println("下载网页失败:", err)return}c.Parse(body)c.Store("提取的数据")
}

在上面的示例中,我们定义了一个Crawler结构体,其中包含了下载、解析和存储等功能。Download方法负责从给定的URL下载网页内容,并返回字节切片。Parse方法负责解析网页内容,提取所需的数据。Store方法负责将提取的数据存储到本地或数据库中。Run方法是爬虫的入口,负责调用其他功能方法来完成整个爬取流程。

3. 使用爬虫封装模块

使用封装的爬虫模块非常简单,只需实例化Crawler结构体并调用Run方法即可。以下是一个使用示例:

package mainimport "crawler"func main() {c := crawler.Crawler{}c.Run("http://example.com")
}

在上面的示例中,我们导入了封装的爬虫模块,实例化Crawler结构体并调用Run方法来启动爬虫程序。这样就完成了一个简单的爬虫任务。

4. 爬虫的进一步封装

上面的示例只是一个简单的爬虫封装模块,实际应用中可能需要更多的功能和扩展。下面是一些可以进一步封装的功能点:

并发爬取

使用Golang的并发特性,可以实现爬虫的并发执行,提高爬取效率。我们可以使用goroutinechannel来实现并发爬取,例如使用一个WorkPool来控制并发数量,每个goroutine负责一个URL的下载、解析和存储。

定时爬取

如果需要定时执行爬取任务,可以使用Golang的time包来实现定时任务。可以创建一个定时器,在每个时间间隔内执行爬取任务。

动态配置

为了增加灵活性,可以将爬虫的配置参数进行动态化。可以使用Golang的flag包来定义命令行参数,或者使用配置文件来配置爬虫的各项参数。

错误处理

在爬虫过程中可能会遇到网络异常、解析错误等问题,我们需要对这些错误进行恰当的处理。可以使用Golang的error类型来表示错误,并进行适当的错误处理和日志记录。

5. 案例1:爬取图片链接

在这个案例中,我们将演示如何使用封装的爬虫模块来爬取网页中的图片链接。我们将使用goquery库来解析HTML并提取图片链接。

首先,我们在Parse方法中添加以下代码来解析网页并提取图片链接:

func (c *Crawler) Parse(body []byte) {doc, err := goquery.NewDocumentFromReader(bytes.NewReader(body))if err != nil {log.Fatal(err)}doc.Find("img").Each(func(i int, s *goquery.Selection) {link, exists := s.Attr("src")if exists {fmt.Println(link)}})
}

在上述代码中,我们使用goquery库的NewDocumentFromReader方法将HTML内容解析为Document对象。然后,我们使用Find方法和选择器img来找到网页中的所有图片元素。然后,我们使用Attr方法获取图片元素的src属性值,即图片链接。最后,我们将图片链接打印出来。

接下来,我们在main函数中添加以下代码来运行爬虫:

func main() {crawler := NewCrawler()crawler.Run("https://www.example.com")
}

这个案例将爬取https://www.example.com网页中的所有图片链接,并将其打印出来。

6. 案例2:爬取文章标题和内容

在这个案例中,我们将使用封装的爬虫模块来爬取网页中的文章标题和内容。我们将使用goquery库来解析HTML并提取文章标题和内容。

首先,我们在Parse方法中添加以下代码来解析网页并提取文章标题和内容:

func (c *Crawler) Parse(body []byte) {doc, err := goquery.NewDocumentFromReader(bytes.NewReader(body))if err != nil {log.Fatal(err)}title := doc.Find("h1").Text()fmt.Println("标题:", title)content := doc.Find("div.content").Text()fmt.Println("内容:", content)
}

在上述代码中,我们使用goquery库的NewDocumentFromReader方法将HTML内容解析为Document对象。然后,我们使用Find方法和选择器h1来找到网页中的标题元素,使用Text方法获取标题文本,并将其打印出来。接着,我们使用Find方法和选择器div.content来找到网页中的内容元素,使用Text方法获取内容文本,并将其打印出来。

接下来,我们在main函数中添加以下代码来运行爬虫:

func main() {crawler := NewCrawler()crawler.Run("https://www.example.com/article/1")
}

这个案例将爬取https://www.example.com/article/1网页中的文章标题和内容,并将其打印出来。

7. 案例3:爬取商品信息

在这个案例中,我们将使用封装的爬虫模块来爬取网页中的商品信息。我们将使用goquery库来解析HTML并提取商品信息。

首先,我们定义一个Product结构体来表示商品信息:

type Product struct {Name  stringPrice string
}

然后,我们在Parse方法中添加以下代码来解析网页并提取商品信息:

func (c *Crawler) Parse(body []byte) {doc, err := goquery.NewDocumentFromReader(bytes.NewReader(body))if err != nil {log.Fatal(err)}doc.Find("div.product").Each(func(i int, s *goquery.Selection) {name := s.Find("h3").Text()price := s.Find("span.price").Text()product := Product{Name:  name,Price: price,}fmt.Println("商品:", product)})
}

在上述代码中,我们使用goquery库的NewDocumentFromReader方法将HTML内容解析为Document对象。然后,我们使用Find方法和选择器div.product来找到网页中的所有商品元素。然后,我们使用Find方法和选择器h3来找到商品元素中的名称元素,使用Text方法获取名称文本。接着,我们使用Find方法和选择器span.price来找到商品元素中的价格元素,使用Text方法获取价格文本。最后,我们将商品名称和价格组成一个Product对象,并将其打印出来。

接下来,我们在main函数中添加以下代码来运行爬虫:

func main() {crawler := NewCrawler()crawler.Run("https://www.example.com/products")
}

这个案例将爬取https://www.example.com/products网页中的所有商品信息,并将其打印出来。

结论

Golang提供了丰富的库和工具来实现爬虫功能。通过封装爬虫模块,我们可以提高代码的可读性和可维护性,并实现更多的功能扩展。希望本文对你理解和使用Golang爬虫封装有所帮助。

参考文献

  • “Building a Web Scraper with Golang” - https://towardsdatascience.com/building-a-web-scraper-with-golang-3f8605543051
  • “An Introduction to Web Scraping with Golang” - https://www.scrapingbee.com/blog/web-scraping-golang/
  • “Web scraping in Go, the easy way” - https://hackernoon.com/web-scraping-in-go-the-easy-way-93a34f3278c7

相关文章:

Golang爬虫封装

引言 爬虫是一种自动化地从网页中提取信息的程序,它在现代互联网的数据获取和分析中扮演着重要的角色。Golang作为一门强大的编程语言,也提供了丰富的工具和库来实现爬虫功能。在本文中,我们将探讨如何使用Golang来封装一个灵活、高效的爬虫…...

技术分享 | 抓包分析 TCP 协议

TCP 协议是在传输层中,一种面向连接的、可靠的、基于字节流的传输层通信协议。 环境准备 对接口测试工具进行分类,可以如下几类: 网络嗅探工具:tcpdump,wireshark代理工具:fiddler,charles&a…...

基于前馈神经网络完成鸢尾花分类

目录 1 小批量梯度下降法 1.0 展开聊一聊~ 1.1 数据分组 1.2 用DataLoader进行封装 1.3 模型构建 1.4 完善Runner类 1.5 模型训练 1.6 模型评价 1.7 模型预测 思考 总结 参考文献 首先基础知识铺垫~ 继续使用第三章中的鸢尾花分类任务,将Softm…...

软考高级系统架构设计师系列之:UML建模、设计模式和软件架构设计章节选择题详解

软考高级系统架构设计师系列之:UML建模、设计模式和软件架构设计章节选择题详解 一、设计模式二、4+1模型三、面向对象的分析模型四、构件五、基于架构的软件设计六、4+1视图七、软件架构风格八、特定领域软件架构九、虚拟机十、架构评估十一、敏感点和权衡点十二、分层结构十…...

成集云 | 电商平台、ERP、WMS集成 | 解决方案

电商平台ERPWMS 方案介绍 电商平台即是一个为企业或个人提供网上交易洽谈的平台。企业电子商务平台是建立在Internet网上进行商务活动的虚拟网络空间和保障商务顺利运营的管理环境;是协调、整合信息流、货物流、资金流有序、关联、高效流动的重要场所。企业、商家…...

吴恩达《机器学习》4-6->4-7:正规方程

一、正规方程基本思想 正规方程是一种通过数学推导来求解线性回归参数的方法,它通过最小化代价函数来找到最优参数。 代价函数 J(θ) 用于度量模型预测值与实际值之间的误差,通常采用均方误差。 二、步骤 准备数据集,包括特征矩阵 X 和目标…...

VO、DTO

DTO DTO(Data Transfer Object) 数据传输对象【前后端交互】 也就是后端开发过程中,用来接收前端传过来的参数,一般会创建一个Java对应的DTO类(UserDTO等等) 因为前端一般传来的是Json格式的数据&#xf…...

RK3566上运行yolov5模型进行图像识别

一、简介 本文记录了依靠RK官网的文档,一步步搭建环境到最终在rk3566上把yolov5 模型跑起来。最终实现的效果如下: 在rk3566 板端运行如下app: ./rknn_yolov5_demo model/RK356X/yolov5s-640-640.rknn model/bus.jpg其中yolov5s-640-640.r…...

汽车标定技术(一):XCP概述

目录 1.汽车标定概述 2.XCP协议由来及版本介绍 3.XCP技术通览 3.1 XCP上下机通信模型 3.2 XCP指令集 3.2.1 XCP帧结构定义 3.2.2 标准指令集 3.2.3 标定指令集 3.2.4 页切换指令集 3.2.5 数据采集指令集 3.2.6 刷写指令集 3.3 ECU描述文件(A2L)概述 3.3.1 标定上位…...

短视频的运营方法

尊敬的用户们,你们好!今天我将为大家带来一篇关于短视频运营的专业文章。在当今互联网时代,短视频已经成为了一个重要的流量入口,掌握正确的运营方法对于企业的发展至关重要。接下来,我将通过以下几个方面为大家详细介…...

GitLab CI/CD 持续集成/部署 SpringBoot 项目

一、GitLab CI/CD 介绍 GitLab CI/CD(Continuous Integration/Continuous Deployment)是 GitLab 提供的一种持续集成和持续部署的解决方案。它可以自动化软件的构建、测试和部署过程,以便开发者更快地、更频繁地发布可靠的产品。 整体过程如…...

第二证券:政策效应逐步显现 A股修复行情有望持续演绎

上星期,A股商场延续企稳反弹的态势,上证指数震荡上涨0.43%;沪深两市日均成交额回升至8700亿元左右;北向资金近一个月初次转为周净买入5.57亿元。 安排观点一起认为,在稳增加、稳预期相关政策持续发力,上市…...

sql逻辑优化

1.分页 通常使用每页条数及第一页作为参数 开发接口 GetMapping("/querySystemList") public List<SystemAduit> querySystemList(RequestParam("keyword") String keyword,RequestParam(name "offset", defaultValue "0") i…...

【数据结构】树与二叉树(一):树(森林)的基本概念:父亲、儿子、兄弟、后裔、祖先、度、叶子结点、分支结点、结点的层数、路径、路径长度、结点的深度、树的深度

文章目录 5.1 树的基本概念5.1.1 树的定义树有序树、无序树 5.1.2 森林的定义5.1.3 树的术语1. 父亲&#xff08;parent&#xff09;、儿子&#xff08;child&#xff09;、兄弟&#xff08;sibling&#xff09;、后裔&#xff08;descendant&#xff09;、祖先&#xff08;anc…...

2024 Android Framework学习大纲之基础理论篇

2024 Android Framework学习大纲之基础理论篇 受到当前经济影响&#xff0c;互联网越来越不景气了,因此Android App开发也是越来越不景气&#xff0c;中小型公司越来越偏向跨平台开发&#xff0c;比如Flutter&#xff0c;这样能节省成本&#xff0c;笔者也曾经是一名6年多工作经…...

【深度学习】Yolov8 区域计数

git&#xff1a;https://github.com/ultralytics/ultralytics/blob/main/examples/YOLOv8-Region-Counter/readme.md 很长时间没有做yolov的项目了&#xff0c;最近一看yolov8有一个区域计数的功能&#xff0c;不得不说很实用啊。 b站&#xff1a;https://www.bilibili.com/vid…...

Windows 系统服务器部署jar包时,推荐使用winsw,将jar包注册成服务,并设置开机启动。

一、其他方式不推荐的原因 1、Spring Boot生成的jar包&#xff0c;可以直接用java -jar运行&#xff0c;但是前提是需要登录用户&#xff0c;而且注销用户后会退出程序&#xff0c;所以不可用。 2、使用计划任务&#xff0c;写一个bat处理文件&#xff0c;里面写java -jar运行…...

npm 包管理

1. 命令 // 查看是否登录 npm who am i // 登录&#xff1a;输入用户名、密码、邮箱、一次性登录密码&#xff08;邮箱接收&#xff09; npm login // 创建 npm init // 快速创建 npm init -y // 发包 npm publish // 发包&#xff08;开源&#xff09; npm publish --access …...

力扣370周赛 -- 第三题(树形DP)

该题的方法&#xff0c;也有点背包的意思&#xff0c;如果一些不懂的朋友&#xff0c;可以从背包的角度去理解该树形DP 问题 题解主要在注释里 //该题是背包问题树形dp问题的结合版&#xff0c;在树上解决背包问题 //背包问题就是选或不选当前物品 //本题求的是最大分数 //先转…...

GPT学习笔记

百度的文心一言 阿里的通义千问 通过GPT能力&#xff0c;提升用户体验和产品力 GPT的出现是AI的iPhone时刻。2007年1月9日&#xff0c;第一代iPhone发布&#xff0c;开启移动互联网时代。新一轮的产业革命。 GPT模型发展时间线&#xff1a; Copilot - 副驾驶 应用&#xf…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...