首页
/
Go-Colly 中文教程
/
Colly 实战:5 分钟爬取 Google Groups 邮件列表
Colly 实战:5 分钟爬取 Google Groups 邮件列表
Google Groups 邮件太多不想手动复制?用 Colly 把主题、作者、正文一次性打包成 JSON!官方 80+ 行示例已被精简为 30 行中文注释版 ,新手也能秒懂。
一、整体思路(先背下来)
线程收集器 :翻 /forum/ 页面,拿“主题列表”
邮件收集器 :进每个主题,爬所有邮件
结果输出 :一个主题 = 一个数组,直接生成 JSON
二、精简中文代码(30 行)
package main
import (
"encoding/json"
"flag"
"log"
"os"
"strings"
"github.com/gocolly/colly/v2"
)
// 单封邮件结构
type Mail struct {
Title string `json:"标题"`
Link string `json:"链接"`
Author string `json:"作者"`
Date string `json:"日期"`
Message string `json:"正文"`
}
func main() {
// 1. 命令行参数:-group=hspbp 可换任意组名
group := flag.String("group", "hspbp", "Google Groups 组名")
flag.Parse()
// 2. 双收集器:线程 + 邮件
threadC := colly.NewCollector()
mailC := colly.NewCollector()
threads := make(map[string][]Mail)
/* ---------- 线程收集器:翻主题 ---------- */
threadC.OnHTML("tr", func(e *colly.HTMLElement) {
ch := e.DOM.Children()
author := strings.TrimSpace(ch.Eq(1).Text())
if author == "" { return } // 被删除的主题
title := strings.TrimSpace(ch.Eq(0).Text())
link, _ := ch.Eq(0).Children().Eq(0).Attr("href")
// 替换为纯 HTML 版本
link = strings.Replace(link, ".com/d/topic", ".com/forum/?_escaped_fragment_=topic", 1)
date := strings.TrimSpace(ch.Eq(2).Text())
log.Printf("发现主题:%s %s", title, link)
mailC.Visit(link)
})
// 翻页
threadC.OnHTML("body > a[href]", func(e *colly.HTMLElement) {
e.Request.Visit(e.Attr("href"))
})
/* ---------- 邮件收集器:爬正文 ---------- */
mailC.OnHTML("body", func(e *colly.HTMLElement) {
subject := e.ChildText("h2")
if _, ok := threads[subject]; !ok {
threads[subject] = []Mail{}
}
e.ForEach("table tr", func(_ int, el *colly.HTMLElement) {
threads[subject] = append(threads[subject], Mail{
Title: strings.TrimSpace(el.ChildText("td:nth-of-type(1)")),
Link: el.ChildAttr("td:nth-of-type(1)", "href"),
Author: strings.TrimSpace(el.ChildText("td:nth-of-type(2)")),
Date: strings.TrimSpace(el.ChildText("td:nth-of-type(3)")),
Message: strings.TrimSpace(el.ChildText("td:nth-of-type(4)")),
})
})
// 翻邮件下一页
if href, ok := e.DOM.Find("> a[href]").Attr("href"); ok {
e.Request.Visit(href)
} else {
log.Printf("主题 [%s] 完成", subject)
}
})
// 3. 启动
startURL := "https://groups.google.com/forum/?_escaped_fragment_=forum/" + *group
threadC.Visit(startURL)
// 4. 输出漂亮 JSON
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
_ = enc.Encode(threads)
}
三、3 步运行
步骤
命令
说明
① 安装
go mod init gg && go get github.com/gocolly/colly/v2
一键拉库
② 保存
复制上方代码 → main.go
零配置
③ 运行
go run main.go -group=hspbp > hspbp.json
生成主题 JSON
四、结果预览(hspbp.json)
{
"How to use Colly with Google Groups": [
{
"标题": "Re: How to use Colly with Google Groups",
"链接": "...",
"作者": "Alice",
"日期": "May 20",
"正文": "You can use OnHTML to extract..."
}
]
}
五、常见问题速查
症状
原因
解决
0 条数据
组名错误或反爬
换组名 + 加 User-Agent
正文乱码
换行符未处理
用 strings.TrimSpace
403 被拦截
缺代理/限速
加 Limit 或代理
六、1 分钟扩展
需求
改动 1 行
爬其他组
-group=golang-nuts
存 CSV
把 JSON 编码换成 csv.NewWriter
存 MongoDB
在 mailC.OnHTML 里写 collection.InsertOne