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文档:官方指南