DEV Community

muskert
muskert

Posted on

用 Apify 搭建 Hacker News 评论爬虫:用 Algolia API 提取科技社区深度讨论

用 Apify 搭建 Hacker News 评论爬虫:用 Algolia API 提取科技社区深度讨论

Hacker News(简称 HN)是硅谷科技圈最核心的新闻聚合社区。每一条热门 story 下面,都有深度的技术讨论——这是做科技市场调研、竞品分析、舆情监控最真实的一手数据宝库。

但 HN 的官方界面没有提供方便的数据导出工具。想批量抓取评论、做趋势分析,纯手工操作根本不可能。

这篇文章介绍如何用 Apify Actor 快速搭建一个 HN 评论爬虫,基于 HN 官方 Algolia API,每小时可抓取数千条评论数据,不需要浏览器,不消耗代理资源,稳定高效。

为什么选 Algolia API?

HN 官方使用 Algolia 提供搜索服务,而 Algolia 的 HN 搜索 endpoint 是公开的,无需 API key,直接请求即可:

https://hn.algolia.com/api/v1/search?query=AI&tags=story
Enter fullscreen mode Exit fullscreen mode

这个 API 返回:

  • 按相关性排序的故事列表
  • 每条故事的标题、URL、分数、评论数、作者、发布时间
  • 支持时间范围过滤和自定义排序

配合 https://hn.algolia.com/api/v1/items/{id} endpoint,还能获取任意故事的完整嵌套评论结构。

核心优势:

  • 无需登录、无需 API key
  • 纯 HTTP 请求,速度快(<100ms 响应)
  • 数据结构化(JSON)
  • 不需要浏览器,资源消耗极低

快速开始

第一步:在 Apify 上找到现成工具

直接访问 Hacker News Comment Scraper,这是本文对应的 Apify Actor。

第二步:配置输入参数

支持 5 种工作模式:

1. search(关键词搜索)

{
  "mode": "search",
  "searchQuery": "AI startup tools",
  "maxStories": 10
}
Enter fullscreen mode Exit fullscreen mode

2. top(热门排行)

{
  "mode": "top",
  "period": "day",
  "maxStories": 20
}
Enter fullscreen mode Exit fullscreen mode

period 可选:day / week / month / year / all

3. new(最新故事)

{
  "mode": "new",
  "maxStories": 30
}
Enter fullscreen mode Exit fullscreen mode

4. comments(评论抓取)

{
  "mode": "comments",
  "storyId": "41870040",
  "maxComments": 50,
  "maxReplies": 5,
  "outputFormat": "threaded"
}
Enter fullscreen mode Exit fullscreen mode

outputFormat 可选 threaded(嵌套结构)或 flat(扁平列表)。

5. full(全量模式)
一次性搜索故事 + 抓取评论,结果包含故事元数据和完整评论树。

第三步:获取结构化数据

运行完成后,数据以 JSON 格式输出,包含:

{
  "mode": "search",
  "query": "AI startup tools",
  "stories_found": 10,
  "items": [
    {
      "id": "41870040",
      "title": "Adobe's new image rotation tool...",
      "url": "https://news.ycombinator.com/item?id=41870040",
      "points": 912,
      "author": "ralusek",
      "num_comments": 268,
      "created_at": "2024-10-17T14:31:18Z"
    }
  ],
  "meta": {
    "actor": "hackernews-comment-scraper",
    "version": "0.2",
    "scraped_at_utc": "2026-04-27T10:00:00Z"
  }
}
Enter fullscreen mode Exit fullscreen mode

评论模式输出:

{
  "story": {
    "story_id": "41870040",
    "story_title": "...",
    "story_points": 912,
    "comments": [
      {
        "id": 41870041,
        "author": "ralusek",
        "text": "Pretty incredible",
        "depth": 0,
        "children": [
          {
            "id": 41870101,
            "author": "jprd",
            "text": "Completely agree...",
            "depth": 1
          }
        ]
      }
    ],
    "total_comments": 258
  }
}
Enter fullscreen mode Exit fullscreen mode

典型应用场景

场景一:科技趋势监控

每天定时抓取 HN 热门故事,了解本周最火的 AI 工具、编程语言、框架趋势。

推荐配置: mode: top, period: week, maxStories: 30

场景二:竞品舆情分析

监控竞品相关的关键词(如公司名、产品名),实时追踪社区讨论。

推荐配置: mode: search, searchQuery: "yourcompetitor", maxStories: 50

场景三:社区情绪分析

抓取特定话题的评论,配合 GPT 做情感分类,识别用户真实态度。

推荐配置: mode: comments, storyId: <target>, outputFormat: flat

场景四:创业情报收集

HN 是创业者的聚集地。监控 show hnask hn 类型的故事,发现新产品的早期用户反馈。

{
  "mode": "search",
  "searchQuery": "show hn OR ask hn",
  "maxStories": 20
}
Enter fullscreen mode Exit fullscreen mode

技术实现细节

核心 API 调用

故事搜索(Algolia):

GET https://hn.algolia.com/api/v1/search
  ?query=<关键词>
  &tags=story
  &hitsPerPage=<数量>
  &numericFilters=created_at_i><时间戳>
  &customRanking=desc(points)
Enter fullscreen mode Exit fullscreen mode

评论抓取(HN Items API):

GET https://hn.algolia.com/api/v1/items/<story_id>
Enter fullscreen mode Exit fullscreen mode

返回嵌套的 children 数组,每条评论包含:

  • id:评论唯一 ID
  • author:作者名
  • text:评论内容(HTML,需处理)
  • created_at:发布时间
  • children:嵌套回复

Python 实现核心代码

import requests
from urllib.parse import quote

ALGOLIA_URL = "https://hn.algolia.com/api/v1"

def search_stories(query, max_stories=10):
    url = f"{ALGOLIA_URL}/search?query={quote(query)}&tags=story&hitsPerPage={max_stories}"
    resp = requests.get(url, headers={"User-Agent": "Apify-HN/1.0"})
    data = resp.json()
    return [{
        "id": hit["objectID"],
        "title": hit["title"],
        "url": hit.get("url") or f"https://news.ycombinator.com/item?id={hit['objectID']}",
        "points": hit.get("points", 0),
        "author": hit.get("author", "unknown"),
        "num_comments": hit.get("num_comments", 0),
    } for hit in data.get("hits", [])]

def get_comments(story_id, max_comments=50):
    url = f"{ALGOLIA_URL}/items/{story_id}"
    resp = requests.get(url)
    data = resp.json()

    def flatten(comments, depth=0):
        result = []
        for c in comments[:max_comments]:
            result.append({
                "id": c["id"],
                "author": c.get("author", "[deleted]"),
                "text": strip_html(c.get("text", "")),
                "depth": depth,
                "children": flatten(c.get("children", []), depth + 1)
            })
        return result

    return flatten(data.get("children", []))
Enter fullscreen mode Exit fullscreen mode

数据处理注意事项

  1. HTML 转义:评论内容返回的是转义 HTML(如 &amp; &lt;),需要用 html.unescape() 或正则清理
  2. 时间格式:Algolia 返回 ISO 8601 格式,转换为时间戳需要 datetime.fromisoformat()
  3. 分页处理:大量评论时需要多次请求(Algolia 单次最多 1000 条)

如何接入自己的应用

Apify Actor 提供完整的 REST API,可以直接在代码中调用:

import requests, json

def run_apify_actor(actor_id, token, input_data):
    # Start actor run
    start_resp = requests.post(
        f"https://api.apify.com/v2/acts/{actor_id}/runs",
        json={"token": token, "input": input_data}
    )
    run_id = start_resp.json()["data"]["id"]

    # Wait for completion
    import time
    while True:
        status = requests.get(
            f"https://api.apify.com/v2/acts/{actor_id}/runs/{run_id}",
            params={"token": token}
        ).json()["data"]["status"]
        if status == "SUCCEEDED":
            break
        time.sleep(5)

    # Get dataset
    dataset_id = requests.get(
        f"https://api.apify.com/v2/acts/{actor_id}/runs/{run_id}/dataset",
        params={"token": token}
    ).json()["data"]["id"]

    items = requests.get(
        f"https://api.apify.com/v2/datasets/{dataset_id}/items",
        params={"token": token}
    ).json()

    return items
Enter fullscreen mode Exit fullscreen mode

定价与资源

该 Actor 使用纯 HTTP 请求,资源消耗极低:

  • 每次运行 CPU 时间:< 5 秒
  • 内存使用:< 64 MB
  • 典型请求成本:$0.0001 – $0.001 / 次

Apify 免费额度 $5/月,可支持数千次调用。

总结

Hacker News 评论爬虫是科技圈市场调研和舆情分析的利器。基于 Algolia API 的实现方案,无需浏览器,速度快,成本低,稳定可靠。

配合 Apify 的定时任务功能,还可以每天自动抓取热门话题,建立自己的科技趋势数据库——这比花几百块买研报便宜太多了,而且数据是一手的。

相关链接:

Top comments (0)