從 API 列表 → 逐條詳情 → 本地 JSON 文件,一條命令完成 Factbase 演講全文抓取。零基礎(chǔ)也能 5 分鐘跑通!
slug + 日期
slug
爬 /transcript/xxx
頁面 <日期>_<slug>.json
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"strconv"
"github.com/gocolly/colly/v2"
)
// 演講全文結(jié)構(gòu)
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 → 觸發(fā)詳情
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))
}
}
步驟 | 命令 | 說明 |
---|---|---|
① 安裝 | go mod init factbase && go get github.com/gocolly/colly/v2 |
一鍵拉庫 |
② 保存 | 復(fù)制上方代碼 → main.go |
零配置 |
③ 運(yùn)行 | go run main.go |
終端實(shí)時(shí)顯示保存進(jìn)度 |
本地生成文件:
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 條數(shù)據(jù) | API 無返回 | 檢查網(wǎng)絡(luò) / 換代理 |
文件中文亂碼 | Windows 默認(rèn)編碼 | 用 VS Code 打開即可 |
403 被攔截 | 缺 UA | 加 colly.UserAgent("Mozilla/5.0...") |
需求 | 改動(dòng) 1 行 |
---|---|
只爬前 10 頁 | i < 11 |
存 CSV | 把 json.MarshalIndent 換成 csv.Writer |
存 MongoDB | 在 OnHTML 里寫 collection.InsertOne |
更多建議: