Colly 实战:抓取 Factbase 演讲全文并保存 JSON
2025-07-14 17:46 更新
从 API 列表 → 逐条详情 → 本地 JSON 文件,一条命令完成 Factbase 演讲全文抓取。零基础也能 5 分钟跑通!
一、整体思路(先背下来)
- 列表收集器:调 API 分页拿
slug + 日期
- 详情收集器:根据
slug
爬/transcript/xxx
页面 - 上下文传递:把日期/文件名随请求一起带过去
- 结果输出:每条演讲保存为一个
<日期>_<slug>.json
二、精简中文代码(30 行)
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"strconv"
"github.com/gocolly/colly/v2"
)
// 演讲全文结构
type Speech struct {
Speaker string `json:"speaker"`
Text string `json:"text"`
}
func main() {
const (
searchAPI = "https://factba.se/json/json-transcript.php?q=&f=&dt=&p="
transcript = "https://factba.se/transcript/"
)
// 1. 列表收集器:只访问 API
listC := colly.NewCollector(colly.AllowedDomains("factba.se"))
// 2. 详情收集器:爬详情页
detailC := listC.Clone()
// 3. 解析详情页 → 保存 JSON
detailC.OnHTML("body", func(e *colly.HTMLElement) {
var speech []Speech
e.ForEach(".topic-media-row", func(_ int, el *colly.HTMLElement) {
speech = append(speech, Speech{
Speaker: el.ChildText(".speaker-label"),
Text: el.ChildText(".transcript-text-block"),
})
})
date := e.Request.Ctx.Get("date")
slug := e.Request.Ctx.Get("slug")
file := colly.SanitizeFileName(date + "_" + slug + ".json")
data, _ := json.MarshalIndent(speech, "", " ")
_ = ioutil.WriteFile(file, data, 0644)
fmt.Printf("✅ 已保存 %s 共 %d 段\n", file, len(speech))
})
// 4. 解析 API → 触发详情
stop := false
listC.OnResponse(func(r *colly.Response) {
type Resp struct {
Data []struct {
Slug string `json:"slug"`
Date string `json:"date"`
} `json:"data"`
}
var resp Resp
_ = json.Unmarshal(r.Body, &resp)
if len(resp.Data) == 0 {
stop = true
return
}
for _, d := range resp.Data {
u := transcript + d.Slug
ctx := colly.NewContext()
ctx.Put("date", d.Date)
ctx.Put("slug", d.Slug)
detailC.Request("GET", u, nil, ctx, nil)
}
})
// 5. 从第 1 页开始,最多 999 页
for i := 1; i < 1000 && !stop; i++ {
_ = listC.Visit(searchAPI + strconv.Itoa(i))
}
}
三、3 步跑通
步骤 | 命令 | 说明 |
---|---|---|
① 安装 | go mod init factbase && go get github.com/gocolly/colly/v2 |
一键拉库 |
② 保存 | 复制上方代码 → main.go |
零配置 |
③ 运行 | go run main.go |
终端实时显示保存进度 |
四、结果示例
本地生成文件:
2023-10-01_trump-ohio-rally.json
2023-09-30_biden-press-briefing.json
...
打开任意 JSON:
[
{
"speaker": "Donald Trump",
"text": "We are going to make America great again..."
},
{
"speaker": "Reporter",
"text": "Mr. President, what about..."
}
]
五、常见问题速查
症状 | 原因 | 解决 |
---|---|---|
0 条数据 | API 无返回 | 检查网络 / 换代理 |
文件中文乱码 | Windows 默认编码 | 用 VS Code 打开即可 |
403 被拦截 | 缺 UA | 加 colly.UserAgent("Mozilla/5.0...") |
六、1 分钟扩展
需求 | 改动 1 行 |
---|---|
只爬前 10 页 | i < 11 |
存 CSV | 把 json.MarshalIndent 换成 csv.Writer |
存 MongoDB | 在 OnHTML 里写 collection.InsertOne |
以上内容是否对您有帮助:
更多建议: