Colly 實(shí)戰(zhàn):3 分鐘抓取 Hacker News 評(píng)論樹

2025-07-14 17:57 更新

官方示例 50+ 行看得頭大?我把它壓縮成 20 行中文注釋版,爬指定帖子的所有評(píng)論,自動(dòng)遞歸成樹形 JSON,瀏覽器直看!

一、整體思路(先背下來(lái))

  1. 傳帖子 ID → 訪問(wèn) item?id=xxx
  2. 每條評(píng)論 <tr class="athing">40px 縮進(jìn)就是層級(jí)
  3. 根據(jù)縮進(jìn)寬度 /40 找到父節(jié)點(diǎn),拼成樹
  4. 輸出漂亮 JSON

二、精簡(jiǎn)中文代碼(20 行)

package main


import (
    "encoding/json"
    "flag"
    "log"
    "os"
    "strconv"
    "strings"


    "github.com/gocolly/colly/v2"
)


// 單條評(píng)論
type Comment struct {
    Author  string     `json:"作者"`
    URL     string     `json:"鏈接"`
    Comment string     `json:"正文"`
    Replies []*Comment `json:"回復(fù)"`
}


func main() {
    // 1. 命令行參數(shù):-id=38861503
    id := flag.String("id", "", "Hacker News 帖子 ID")
    flag.Parse()
    if *id == "" {
        log.Fatal("缺少 -id 參數(shù),示例:-id=38861503")
    }


    c := colly.NewCollector()
    var roots []*Comment


    // 2. 解析每條評(píng)論
    c.OnHTML(".comment-tree tr.athing", func(e *colly.HTMLElement) {
        indent, _ := strconv.Atoi(e.ChildAttr("td.ind img", "width"))
        depth := indent / 40 // 40px 一級(jí)


        cmt := &Comment{Replies: []*Comment{}}
        e.Unmarshal(cmt)                     // 自動(dòng)填充 Author/URL/Comment
        cmt.Comment = strings.TrimSpace(cmt.Comment)


        // 3. 找到父節(jié)點(diǎn)并掛載
        parent := roots
        for i := 0; i < depth; i++ {
            if len(parent) == 0 {
                break
            }
            parent = parent[len(parent)-1].Replies
        }
        parent = append(parent, cmt)
    })


    // 4. 開始
    c.Visit("https://news.ycombinator.com/item?id=" + *id)


    // 5. 輸出漂亮 JSON
    enc := json.NewEncoder(os.Stdout)
    enc.SetIndent("", "  ")
    _ = enc.Encode(roots)
}

三、3 步運(yùn)行

步驟 命令 說(shuō)明
① 安裝 go mod init hn && go get github.com/gocolly/colly/v2 一鍵拉庫(kù)
② 保存 復(fù)制代碼 → main.go 零配置
③ 爬取 go run main.go -id=38861503 > result.json JSON 立即生成

四、結(jié)果預(yù)覽(result.json)

[
  {
    "作者": "pg",
    "鏈接": "item?id=38861503",
    "正文": "This is the root comment...",
    "回復(fù)": [
      {
        "作者": "user123",
        "鏈接": "item?id=38861504",
        "正文": "Good point!",
        "回復(fù)": []
      }
    ]
  }
]

五、常見問(wèn)題 30 秒排查

癥狀 原因 解決
0 條評(píng)論 帖子 ID 錯(cuò)誤/反爬 換熱門帖子 + 加 UA
層級(jí)錯(cuò)亂 縮進(jìn)寬度改變 確認(rèn) 40px 仍適用
中文亂碼 終端編碼 用 VS Code 打開 JSON

六、1 分鐘擴(kuò)展

需求 改動(dòng) 1 行
存 CSV 把 JSON 編碼換成 csv.Writer
存數(shù)據(jù)庫(kù) OnHTML 里寫 INSERT
爬多帖 循環(huán)不同 -id 參數(shù)
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)