Go爬虫开发学习记录
Go爬虫开发学习记录
基础篇:使用net/http库
Go的标准库net/http
提供了完善的HTTP客户端功能,是构建爬虫的基石:
package mainimport ("fmt""io""net/http"
)func fetchPage(url string) string {// 创建自定义HTTP客户端client := &http.Client{}// 构建GET请求req, _ := http.NewRequest("GET", url, nil)// 设置请求头模拟浏览器req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)")req.Header.Add("Cookie", "example_cookie=value")// 发送请求resp, err := client.Do(req)if err != nil {fmt.Println("请求错误:", err)return ""}defer resp.Body.Close() // 确保关闭响应体// 检查状态码if resp.StatusCode != 200 {fmt.Println("状态码错误:", resp.StatusCode)return ""}// 读取响应内容body, err := io.ReadAll(resp.Body)if err != nil {fmt.Println("读取失败:", err)return ""}return string(body)
}func main() {url := "https://www.runoob.com/go/go-tutorial.html"htmlContent := fetchPage(url)fmt.Println(htmlContent)
}
解析:
- 自定义HTTP客户端:通过
&http.Client{}
创建可配置的客户端实例 - 请求头设置:添加User-Agent和Cookie模拟浏览器行为
- 错误处理:全面处理网络请求、状态码和读取错误
- 资源清理:使用defer确保响应体正确关闭
进阶篇:HTML解析与内容提取
获取HTML只是第一步,关键是从中提取有价值的信息:
import ("golang.org/x/net/html""strings"
)func parseHTML(htmlStr string) (title, content string) {// 解析HTML文档doc, err := html.Parse(strings.NewReader(htmlStr))if err != nil {fmt.Println("解析错误:", err)return}// 递归查找标题var findTitle func(*html.Node)findTitle = func(n *html.Node) {if n.Type == html.ElementNode && n.Data == "title" {for c := n.FirstChild; c != nil; c = c.NextSibling {if c.Type == html.TextNode {title = c.Datareturn}}}for c := n.FirstChild; c != nil; c = c.NextSibling {findTitle(c)}}findTitle(doc)// 提取所有文本内容var extractText func(*html.Node)extractText = func(n *html.Node) {if n.Type == html.TextNode {trimmed := strings.TrimSpace(n.Data)if trimmed != "" {content += trimmed + "\n"}}for c := n.FirstChild; c != nil; c = c.NextSibling {extractText(c)}}extractText(doc)return
}func main() {htmlContent := fetchPage("https://www.runoob.com/go/go-tutorial.html")title, content := parseHTML(htmlContent)fmt.Println("标题:", title)fmt.Println("内容:\n", content)
}
解析:
- 递归遍历DOM树:深度优先搜索(DFS)遍历所有节点
- 节点类型判断:
ElementNode
:HTML元素节点(标签)TextNode
:文本内容节点
- 内容清洗:
strings.TrimSpace
去除空白字符 - 精确提取:通过标签名(
title
)定位特定内容
高效篇:使用Colly+GoQuery框架
对于复杂爬取任务,Colly+GoQuery组合提供更强大的解决方案:
package mainimport ("fmt""log""strings""time""bytes""github.com/gocolly/colly""github.com/PuerkitoBio/goquery"
)func main() {// 1. 创建Collector实例c := colly.NewCollector(colly.AllowedDomains("runoob.com", "www.runoob.com"),colly.UserAgent("Mozilla/5.0..."),colly.Async(true), // 启用异步)// 2. 设置爬取规则c.Limit(&colly.LimitRule{DomainGlob: "*runoob.com*",Parallelism: 2, // 并发数Delay: 1 * time.Second,RandomDelay: 1 * time.Second,})// 3. 注册回调函数c.OnRequest(func(r *colly.Request) {fmt.Println("访问:", r.URL)})c.OnError(func(_ *colly.Response, err error) {log.Println("错误:", err)})// 4. 使用GoQuery解析c.OnHTML("html", func(e *colly.HTMLElement) {doc, err := goquery.NewDocumentFromReader(bytes.NewReader(e.Response.Body))if err != nil {log.Println("解析失败:", err)return}// 提取标题title := doc.Find("title").Text()fmt.Println("页面标题:", title)// 提取导航菜单doc.Find("#leftcolumn a").Each(func(i int, s *goquery.Selection) {fmt.Printf("菜单%d: %s\n", i+1, strings.TrimSpace(s.Text()))})// 提取文章内容doc.Find("div.article").Each(func(i int, s *goquery.Selection) {section := s.Find("h1").Text()content := strings.TrimSpace(s.Text())fmt.Printf("\n章节%d: %s\n内容: %s\n", i+1, section, content)})})// 5. 开始爬取c.Visit("https://www.runoob.com/go/go-tutorial.html")c.Wait() // 等待异步任务fmt.Println("爬取完成")
}
Colly核心优势:
-
智能限速控制:
- 自动延迟请求
- 随机延迟避免检测
- 并发控制保护服务器
-
强大的选择器:
- CSS选择器语法
- 链式调用
- 支持复杂嵌套选择
-
异步高性能:
- 协程并发处理
- 自动队列管理
- 高效资源利用
-
扩展性强:
- 中间件支持
- 自定义存储后端
- 请求重试机制
可视化爬虫工具:易采集EasySpider
对于非技术人员或快速原型开发,可视化爬虫工具是绝佳选择:
无代码可视化爬虫
易采集EasySpider 核心特点:
- 零代码可视化操作
- 浏览器自动化录制
- 智能数据提取
- 定时任务调度
- 云存储支持
适用场景:快速数据采集原型、非技术用户、简单爬取任务
爬虫开发最佳实践
-
遵守Robots协议:
User-agent: * Allow: /public/ Disallow: /private/
-
道德规范:
- 尊重网站版权声明
- 避免高频请求
- 不爬取敏感信息
-
反爬虫对策:
- 轮换User-Agent
- 使用代理IP池
- 模拟人类操作间隔
- 处理验证码机制
-
错误处理:
- 网络异常重试
- 状态码处理
- 超时控制
-
数据存储:
- 结构化数据:MySQL/PostgreSQL
- 半结构化:MongoDB/Elasticsearch
- 文件存储:CSV/JSON/Parquet
总结与学习路径
Go爬虫开发技术栈演进:
学习建议:
- 掌握基础:熟练使用net/http和HTML解析
- 框架实践:深入Colly+GoQuery组合应用
- 项目实战:构建完整爬虫系统
- 拓展进阶:研究分布式爬虫架构
- 工具互补:了解可视化工具辅助开发
资源推荐:
- 官方文档:Go net/http包
- Colly框架:GitHub仓库
- GoQuery文档:官方指南
相关文章:
Go爬虫开发学习记录
Go爬虫开发学习记录 基础篇:使用net/http库 Go的标准库net/http提供了完善的HTTP客户端功能,是构建爬虫的基石: package mainimport ("fmt""io""net/http" )func fetchPage(url string) string {// 创建自定…...

前端异步编程全场景解读
前端异步编程是现代Web开发的核心,它解决了浏览器单线程执行带来的UI阻塞问题。以下从多个维度进行深度解析: 一、异步编程的核心概念 JavaScript的执行环境是单线程的,这意味着在同一时间只能执行一个任务。为了不阻塞主线程,J…...

分布式光纤声振传感技术原理与瑞利散射机制解析
分布式光纤传感技术(Distributed Fiber Optic Sensing,简称DFOS)作为近年来迅速发展的新型感知手段,已广泛应用于边界安防、油气管道监测、结构健康诊断、地震探测等领域。其子类技术——分布式光纤声振传感(Distribut…...

RocketMQ 客户端负载均衡机制详解及最佳实践
延伸阅读:🔍「RocketMQ 中文社区」 持续更新源码解析/最佳实践,提供 RocketMQ 专家 AI 答疑服务 前言 本文介绍 RocketMQ 负载均衡机制,主要涉及负载均衡发生的时机、客户端负载均衡对消费的影响(消息堆积/消费毛刺等…...
Q1起重机指挥理论备考要点分析
Q1起重机指挥理论备考要点分析 一、考试重点内容概述 Q1起重机指挥理论考试主要包含三大核心模块:安全技术知识(占40%)、指挥信号规范(占30%)和法规标准(占30%)。考试采用百分制,8…...
c++算法学习3——深度优先搜索
一、深度优先搜索的核心概念 DFS算法是一种通过递归或栈实现的"一条路走到底"的搜索策略,其核心思想是: 深度优先:从起点出发,选择一个方向探索到底,直到无路可走 回溯机制:遇到死路时返回最近…...
如何让非 TCP/IP 协议驱动屏蔽 IPv4/IPv6 和 ARP 报文?
——从硬件过滤到协议栈隔离的完整指南 引言 在现代网络开发中,许多场景需要定制化网络协议(如工业控制、高性能计算),此时需确保驱动仅处理特定协议,避免被标准协议(如 IPv4/IPv6/ARP)干扰。本文基于 Linux 内核驱动的实现,探讨如何通过硬件过滤、驱动层拦截和协议栈…...
组合模式:构建树形结构的艺术
引言:处理复杂对象结构的挑战 在软件开发中,我们常遇到需要处理部分-整体层次结构的场景: 文件系统中的文件与文件夹GUI中的容器与组件组织结构中的部门与员工菜单系统中的子菜单与菜单项组合模式正是为解决这类问题而生的设计模式。它允许我们将对象组合成树形结构来表示&…...

【SSM】SpringMVC学习笔记7:前后端数据传输协议和异常处理
这篇学习笔记是Spring系列笔记的第7篇,该笔记是笔者在学习黑马程序员SSM框架教程课程期间的笔记,供自己和他人参考。 Spring学习笔记目录 笔记1:【SSM】Spring基础: IoC配置学习笔记-CSDN博客 对应黑马课程P1~P20的内容。 笔记2…...
Spring Boot SQL数据库功能详解
Spring Boot自动配置与数据源管理 数据源自动配置机制 当在Spring Boot项目中添加数据库驱动依赖(如org.postgresql:postgresql)后,应用启动时自动配置系统会尝试创建DataSource实现。开发者只需提供基础连接信息: 数据库URL格…...
TI德州仪器TPS3103K33DBVR低功耗电压监控器IC电源管理芯片详细解析
1. 基本介绍 TPS3103K33DBVR 是 德州仪器(Texas Instruments, TI) 推出的一款 低功耗电压监控器(Supervisor IC),属于 电源管理芯片(PMIC) 类别,主要用于 系统复位和电压监测。 2. …...

C++课设:实现本地留言板系统(支持留言、搜索、标签、加密等)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、项目功能概览与亮点分析1. 核心功能…...

【见合八方平面波导外腔激光器专题系列】用于干涉光纤传感的低噪声平面波导外腔激光器2
----翻译自Mazin Alalus等人的文章 摘要 1550 nm DWDM 平面波导外腔激光器具有低相位/频率噪声、窄线宽和低 RIN 等特点。该腔体包括一个半导体增益芯片和一个带布拉格光栅的平面光波电路波导,采用 14 引脚蝶形封装。这种平面波导外腔激光器设计用于在振动和恶劣的…...

Xcode 16.2 版本 pod init 报错
Xcode 版本升级到 16.2 后,项目执行 pod init 报错; ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchron…...

timestamp时间戳转换工具
作为一名程序员,一款高效的 在线转换工具 (在线时间戳转换 计算器 字节单位转换 json格式化)必不可少!https://jsons.top 排查问题时非常痛的点: 经常在秒级、毫秒级、字符串格式的时间单位来回转换,于是决定手撸一个…...
分布式计算框架学习笔记
一、🌐 为什么需要分布式计算框架? 资源受限:单台机器 CPU/GPU 内存有限。 任务复杂:模型训练、数据处理、仿真并发等任务耗时严重。 并行优化:通过任务拆分和并行执行提升效率。 可扩展部署:适配从本地…...

数据库管理与高可用-MySQL故障排查与生产环境优化
目录 #1.1MySQL单案例故障排查 1.1.1MySQL常见的故障排查 1.1.2MySQL主从故障排查 #2.1MySQL优化 2.1.1硬件方面的优化 2.1.2进程方面的优化 #3.1MySQL存储引擎 3.1.1 MyISAM存储引擎 3.1.2 InnoDB存储引擎 1.1MySQL单案例故障排查 1.1.1MySQL常见的故障排查 (1&…...
rk3506上移植lvgl应用
本文档介绍如何在开发板上运行以及移植LVGL。 1. 移植准备 硬件环境:开发板及其配套屏幕 开发板镜像 主机环境:Ubuntu 22.04.5 2. LVGL启动 出厂系统默认配置了 LVGL,并且上电之后默认会启动 一个LVGL应用 。 LVGL 的启动脚本为/etc/init.d/pre_init/S00-lv_demo,…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术点解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术点解析 第一轮:基础概念问题 请解释Spring框架的核心容器是什么?它的作用是什么? 程序员JY回答:Spring框架的核心容器是IoC容器(控制反转…...
Flask和Django,你怎么选?
Flask 和 Django 是 Python 两大最流行的 Web 框架,但它们的设计哲学、目标和适用场景有显著区别。以下是详细的对比: 核心区别:哲学与定位 Django: 定位: "全栈式" Web 框架。奉行"开箱即用"的理念。 哲学: "包含…...

LangChain + LangSmith + DeepSeek 入门实战:构建代码生成助手
本文基于 Jupyter Notebook 实践代码,结合 LangChain、LangSmith 和 DeepSeek 大模型,手把手演示如何构建一个代码生成助手,并实现全流程追踪与优化。 一、环境准备与配置 1. 安装依赖 pip install langchain langchain_openai2. 设置环境变…...
湖北理元理律师事务所:债务清偿方案中的法律技术革新
文/金融法律研究组 当前债务服务市场存在结构性矛盾:债权人追求快速回款,债务人需要喘息空间。湖北理元理律师事务所通过创新法律技术,在《企业破产法》《民法典》框架下构建梯度清偿模型,实现多方利益平衡。 一、个人债务优化的…...
大模型的LoRa通讯详解与实现教程
一、LoRa通讯技术概述 LoRa(Long Range)是一种低功耗广域网(LPWAN)通信技术,由Semtech公司开发,特别适合于物联网设备的长距离、低功耗通信需求。LoRa技术基于扩频调制技术,能够在保持低功耗的同时实现数公里甚至数十公里的通信距离。 LoRa的主要特点 长距离通信:在城…...

【Elasticsearch基础】Elasticsearch批量操作(Bulk API)深度解析与实践指南
目录 1 Bulk API概述 1.1 什么是批量操作 1.2 Bulk API的优势 2 Bulk API的工作原理 2.1 请求处理流程 2.2 底层机制 3 Bulk API的使用方法 3.1 基本请求格式 3.2 操作类型示例 3.3 响应格式 4 Bulk API的最佳实践 4.1 批量大小优化 4.2 错误处理策略 4.3 性能调…...
PCA笔记
✅ 问题本质:为什么让矩阵 TT 的行列式为 1? 这个问题通常出现在我们对数据做**线性变换(旋转/缩放)**的时候,比如在 PCA 中把数据从原始坐标系变换到主成分方向时。 📌 回顾一下背景 在 PCA 中ÿ…...

MySQL 数据库深度剖析:事务、SQL 优化、索引与 Buffer Pool
在当今数据驱动的时代,数据库作为数据存储与管理的核心,其性能与可靠性至关重要。MySQL 作为一款广泛使用的开源数据库,在众多应用场景中发挥着关键作用。在这篇博客中,我将围绕 MySQL 数据库的核心知识展开,涵盖事务及…...

MAZANOKE结合内网穿透技术实现跨地域图像优化服务的远程访问过程
文章目录 前言1. 关于MAZANOKE2. Docker部署3. 简单使用MAZANOKE4. 安装cpolar内网穿透5. 配置公网地址6. 配置固定公网地址总结 前言 在数字世界高速发展的今天,您是否察觉到那些静默增长的视觉数据正在悄然蚕食存储空间?随着影像记录成为日常习惯&…...
迁移科技3D视觉系统:重塑纸箱拆垛场景的智能革命
一、传统拆垛场景的困局与破局之道 在汽车零部件仓库中,每天有超过2万只异形纸箱需要拆垛分拣。传统人工拆垛面临三大挑战: 效率瓶颈:工人每小时仅能处理200-300件,且存在间歇性疲劳安全隐患:20kg以上重箱搬运导致年…...

World-writable config file /etc/mysql/mysql.conf.d/my.cnf is ignored
https://stackoverflow.com/questions/53741107/mysql-in-docker-on-ubuntu-warning-world-writable-config-file-is-ignored 修改权限 -> 重启mysql # 检查字符集配置 SHOW VARIABLES WHERE Variable_name IN (character_set_server, character_set_database ); --------…...
JS的传统写法 vs 简写形式
一、条件判断与逻辑操作 三元运算符简化条件判断 // 传统写法 let result; if (someCondition) {result yes; } else {result no; }// 简写方式 const result someCondition ? yes : no;短路求值 // 传统写法 if (condition) {doSomething(); }// 简写方式 condition &…...