你不会想下载整个 Hacker News 吧
Jason Thorsness
githubgithub iconlinkedinlinkedin icontwittertwitter icon
25 — Apr 28 25
你不会想下载整个 Hacker News 吧
25 — Apr 28 25 share ontwitter icon share ontwitter icon
TLDR: 我已经下载了
现在我可以用 DuckDB 分析它了。看看随着时间推移,关键主题在评论和帖子中出现的比例吧!
00.010.020.030.040.050.060.070.085/14/20075/14/20085/14/20095/14/20105/14/20115/14/20125/14/20135/14/20145/14/20155/14/20165/14/20175/14/20185/14/20195/14/20205/14/20215/14/20225/14/20235/14/2024The Rise Of Rustavg_python_12wavg_javascript_12wavg_java_12wavg_ruby_12wavg_rust_12w 00.0010.0020.0030.0040.0050.0060.0070.0080.0090.015/14/20075/14/20085/14/20095/14/20105/14/20115/14/20125/14/20135/14/20145/14/20155/14/20165/14/20175/14/20185/14/20195/14/20205/14/20215/14/20225/14/20235/14/2024The Progression of Postgresavg_mysql_12wavg_postgres_12wavg_mongo_12wavg_redis_12wavg_sqlite_12w
第一部分:趁着管理员睡着了,全部下载下来
为了构建 hn.unlurker.com,我写了一个 HN API client。 已经有很多其他的客户端了,但我想要在一个新的项目上尝试最新的 Go 功能和 linters。 我很高兴我这么做了;这非常有趣。
该客户端可以检索活动的条目、条目列表等等(评论和帖子在 HN API 中被称为 "items")。 虽然我的项目只需要最近的条目,但为了完整性,我添加了 "scan" 功能,它可以按顺序从零到最新或者反过来下载所有条目。
我在想,我能直接下载所有内容吗? 从几千个条目推断,它只有几十 GiB 的 JSON。 我想我应该尝试一下。
hn scan --no-cache --asc -c- -o full.json
我不得不几次使用 CTRL-C 中止一个停滞的下载,但是 scan 是可恢复的,所以在几个小时后我就完成了。 我得到了一个 20 GiB 的 JSON 文件,其中包含 Hacker News 上发生过的所有事情,我可以随时重新运行上面的命令来 "补充" 最新的内容。 但是我能用它做什么呢?
第二部分:喂鸭子
首先,我只是用 grep 搜索东西。 短语 "correct horse battery staple" 在网站上出现了多少次? 还不少:231 次(最后一次就在今天)。 但是 grep 搜索太老套了,所以我决定尝试 DuckDB。
在数据库领域,DuckDB 是独一无二的:一个超快的嵌入式分析执行引擎,也可以作为命令行工具使用。 我一天中的大部分时间都在与另一个数据库打交道(这是我的同事们会寻找的推广),但我一直想尝试 DuckDB,它似乎非常适合这项一次性任务。
事实证明,对于像我这样的新手来说,他们的新 UI 非常容易使用。 并且 LLM 在帮助制作 SQL 查询方面也相当不错。 我只需要导入数据:
CREATE TABLE items AS
SELECT *
FROM read_json_auto('/home/jason/full.json', format='nd', sample_size=-1);
然后查询它。 这是一个 12 周移动平均的包含我感兴趣的术语的条目占总条目的比例:
WITH weekly AS (
SELECT
DATE_TRUNC('week', TO_TIMESTAMP(time)) AS week_start,
COUNT(*) FILTER (WHERE text ILIKE '%python%')::float / NULLIF(COUNT(*),0)
AS python_prop,
COUNT(*) FILTER (WHERE text ILIKE '%javascript%')::float / NULLIF(COUNT(*),0)
AS javascript_prop,
COUNT(*) FILTER (WHERE text ILIKE '%java%')::float / NULLIF(COUNT(*),0)
AS java_prop,
COUNT(*) FILTER (WHERE text ILIKE '%ruby%')::float / NULLIF(COUNT(*),0)
AS ruby_prop,
COUNT(*) FILTER (WHERE text ILIKE '%rust%')::float / NULLIF(COUNT(*),0)
AS rust_prop
FROM items
GROUP BY week_start
)
SELECT
week_start,
AVG(python_prop) OVER (
ORDER BY week_start
ROWS BETWEEN 11 PRECEDING AND CURRENT ROW
) AS avg_python_12w,
AVG(javascript_prop) OVER (
ORDER BY week_start
ROWS BETWEEN 11 PRECEDING AND CURRENT ROW
) AS avg_javascript_12w,
AVG(java_prop) OVER (
ORDER BY week_start
ROWS BETWEEN 11 PRECEDING AND CURRENT ROW
) AS avg_java_12w,
AVG(ruby_prop) OVER (
ORDER BY week_start
ROWS BETWEEN 11 PRECEDING AND CURRENT ROW
) AS avg_ruby_12w,
AVG(rust_prop) OVER (
ORDER BY week_start
ROWS BETWEEN 11 PRECEDING AND CURRENT ROW
) AS avg_rust_12w
FROM weekly
ORDER BY week_start;
总的来说,DuckDB 似乎非常适合分析这种规模的数据集。
下一步
既然我已经下载了所有 Hacker News 的内容,我就可以在它上面训练数百个基于 LLM 的机器人,并将它们作为贡献者运行,慢慢地、不可避免地用中文房间振荡器的输出来取代所有的人类文本,从而永远地回响和回收过去。
或者,我认为这个项目我完成了。 别人必须把它带到下一个逻辑步骤。
感谢阅读! 请查看 hn.unlurker.com,看看我的 其他文章,或者在 X 上找到我。
Top
TermsPrivacy