独立开发·阅读约 1 分钟·
周末花 10 美元,我造了个只搜独立创作者的 50 万域名搜索引擎

周末花 10 美元,我造了个只搜独立创作者的 50 万域名搜索引擎

受够了搜索结果全是企业文档和 SEO 垃圾?一位开发者用周末时间、约 10 美元 GPU 租费和一个小型本地模型,给自己建了覆盖 56 万个域名的个人搜索引擎——并开源了全部代码。

原文来源:Marlin Blog — 一位开发者用周末时间、约 10 美元成本和一个小型本地模型,给自己造了一个覆盖 56 万个域名的个人搜索引擎,专门用来找独立创作者的作品。

周日凌晨两点,Alex Morley Finch 睡不着,又一次对搜索引擎感到恼火。他在意的那类查询——个人作品集、独立杂志、奇怪的小型艺术项目、一个人的软件——总是被埋在成堆的企业文档和 SEO 垃圾底下。于是他做了一件凌晨两点该做的事:打开终端,写下计划。

"我想做一个只给自己用的搜索引擎。互联网上大约有四千万个域名,我们给每个存一点元数据。就算每个 1KB,也就 40GB,完全可行。"

到周三中午,他已经编目了 560,183 个网站首页,然后决定收手。整个项目大约花了 10 美元、一晚的 GPU 租用和几个小时的盯梢时间,最终索引在磁盘上不到 1GB。

架构:四个进程,各司其职

整个系统由四个进程组成,其中三个跑在自己电脑上,一个租来的 GPU 从不直接碰数据库:

  • fetcher(抓取器):取一个待处理的域名,先试 HTTPS 再试 HTTP,用简单的 HTML 解析器抓标题、正文和出链,不做 JavaScript 渲染
  • worker(工作进程):取一个就绪的域名,空页面、停放域名和机器人验证墙直接跳过,否则让一个小型本地模型(Gemma 4B)生成名称、两三句摘要、分类和标签,用完即清掉正文文本
  • steward(管家):不碰主队列,专门抽样那些产出异常多页面的域名,问模型"屏蔽、保留、还是不确定",悄悄维护黑名单
  • API 和网页 UI:带过滤的搜索、可切换的分类隐藏页、能看到流水线实时状态的仪表盘

关键设计是"用完即弃":抓取器抓到的正文只存在域名自己的数据库行里,模型读完立刻清空。四千万行乘几 KB 的原始文本会迅速吃光磁盘,而这些文本只在模型阅读的那几秒里有价值。

—— 广告 ——

最大的发现:互联网 90% 是企业网站

第一个版本几个小时内就跑通了,但周日下午他看了一眼实际编目的内容——"这是错的互联网"。超过 90% 是企业网站和文档,种子列表有偏差,爬虫对接下来该追什么也没有主见。

他没用屏蔽,因为"屏蔽"感觉对但实际是错的:一个无聊的企业文档页可能链向某个人的个人博客,屏蔽会丢掉这些线索。替代方案是给队列加权:被分类为"作品集""独立杂志""软件"的页面,其出链优先级大幅上调;"企业""文档"类的下调。一个文本文件 category-priority.txt 成了整个周末的方向盘,调一个数字,观察一小时,再调。

当天下午他清空了两次数据库——质量差到不如重来。两个 bug 很有代表性:一个网站的摘要字段只有"academic-profile"(模型把分类标签塞错了槽位);另一个 GoDaddy 域名停放页几乎没内容,模型因为主机名里有个"furry"单词,硬是编造出一个完整"兽人社区"网站。教训是:可见文本优先于标题,标题优先于域名猜测,接近空白的页面干脆别问模型。

周日晚上:Tumblr 不是互联网

到了晚上,Tumblr 和 Neocities 博客以压倒性数量涌入,眼看要占领整个索引。第一反应是屏蔽,但 Neocities 恰恰是他要找的那种美学。真正的解法是设上限:主域名永远放行,但某个根域名产出超过 100 个子域后,就不再入队新的。这条规则一次删掉了 4.5 万个排队页面。Tumblr 最终还是贡献了 9000 多个页面,但不再垄断全局。

周一早上来了同款问题:论坛农场和中国 B2B 供应商微站借着"论坛"分类的加成,钻进一堆近似重复页面。这次他把"论坛"权重狠狠降级,并开始维护显式的黑名单文件。

租 GPU:先租错,再租对

他自己的消费级显卡本地跑摘要大约每秒一页,开发 prompt 够用,填索引就 hopeless。于是租了云 GPU。第一个方案用了个包装库,坚持要为单张 GPU 拉起分布式计算框架,结果框架和宿主机抢 CPU,他付着 GPU 的钱却一直被 CPU 争用拖后腿。扔掉包装库、直接跑开源推理服务后,又遇到冷启动高并发崩溃——其实是第一批请求的内存尖峰,改成逐步加大并发就解决了。

真正干活的是带完整独占 CPU 核的中端工作站 GPU。这个"专用 CPU 配额"比 GPU 型号本身更重要:持续吞吐约每分钟 600 条摘要,租金每小时约 35 美分。算下来一美元可以编目十万个网站。

那个让规模翻近十倍的小进程

周一深夜,爬虫还在跑,他问了自己一个问题:这个规模下没法人工盯坏螺旋,能不能让一个小进程从产出异常多的域名里抽样五到十条已完成的页面,让模型自己判断要不要屏蔽?

这就是 steward 的由来,也是索引从 6.5 万涨到 56 万而没有靠人盯着的关键。它跑在本地显卡和 LM Studio 上,判断从不和填索引的租用 GPU 抢资源。整个运行期间它自动封了 177 个问题域名,几乎全是酒店和预订农场,而大学和大型平台这类"子域多但合法"的站点都被正确放行。

最坑的地方:让模型自由发挥的分类体系

爬取和租 GPU 是有趣的部分,真正会咬人的是分类和标签管理。他让模型自由发明分类和标签,理由是让模型教他分类法而不是他先猜一套——起步快,但最终得到 671 个分类(很多只用过一次)和超过 12.1 万个标签(一半以上只出现一次,因为模型每次拼写略有差异)。他手写了一个合并工具清理最严重的部分,但这撑不过玩具项目阶段。给想做大的人的建议很直接:要么一开始就限定模型用固定分类列表,要么为清理预算真实的时间,"让模型自由发挥"会很快追上你。

另一个真实的规模问题是 prompt 和爬取方向的持续调优。所有修复都不是来自什么聪明的一次性 prompt,而是来自几天里反复观察生产数据、微调权重——看真实输出,调一个杠杆,再看。这个循环比任何前期规划都管用。

值得一试吗

如果你想要一个只返回你真正想找的东西的搜索引擎,作者认为周末完全可行,成本也低到 GPU 账单不构成理由。可复用的形状是:抓取和摘要分离(慢网络不拖累贵 GPU)、加权队列而不是硬屏蔽分类、封子域而不是封平台、空页面和停放页面直接跳过模型、规模变大后配一个自动垃圾检测器。

索引里最后有近 2.7 万个真实非营利组织——食品银行、野生动物慈善机构、公民团体,随手抽查都是真东西。"一个开始几乎没想到的分类,成了索引里最强的部分之一,这让我觉得周末没白过。"

数据库暂时不公开,但代码已开源:Marlin。想自己爬的话,把爬虫指向你自己的好奇心就行。

分享到
微博Twitter

© 2026 四月

原文链接:https://www.aprilzz.com/indie/marlin-500k-search-engine