10美元构建域名搜索引警:SQLite+FastAPI实现50万记录快速检索

发布时间:2026/10/24 5:10:19

10美元构建域名搜索引警:SQLite+FastAPI实现50万记录快速检索 这次我们来看一个很有意思的独立开发项目作者用一个周末的时间、大约 10 美元的成本搭建了一套覆盖 50 万条域名记录的搜索引警面向的是 makers——独立开发者、创客、经常要起项目名和选域名的人。这类工具解决的痛点非常具体做产品前要起名字起完名字要确认域名还在不在还要看相近的域名是否被抢注。手动去注册商网站一个个查速度慢、体验差、来回切换页面很折腾。于是就有了这种思路把几十万条域名记录提前拉进本地数据库用关键词搜索、后缀过滤、长度筛选来快速缩小候选范围。相比“打开注册商慢慢试”效率不是一个量级。值得关注的是这组数字背后的技术取舍50 万条数据量不算大但也不是 Excel 能处理的规模10 美元预算意味着不能上重型基础设施一个周末开发意味着技术栈必须足够简单、足够顺手。这三个条件组合下来基本决定了它不会走“Elasticsearch 集群 多节点部署”的路线而是轻量、单机、够用就行的方案。这篇文章会把这类“小成本域名搜索引警”的完整搭建思路拆开讲一遍数据从哪来、怎么清洗入库、用什么存储方案、搜索逻辑怎么写、如何把能力包装成 HTTP API以及部署上线时怎么把成本控制在个位数美元。如果你正在考虑做类似的工具站、内部搜索服务或者只是想把“搜索”这个能力加进自己的独立开发流程里这篇文章可以直接收藏。1. 核心能力速览先给一张规格表快速判断这个项目适不适合你。能力项说明项目类型域名搜索引警 / 轻量级域名查询工具数据规模约 50 万条域名记录项目描述核心功能关键词搜索、TLD 后缀过滤、域名长度筛选、状态标注目标用户makers、独立开发者、创业者、SEO/品牌调研人员开发成本约 10 美元项目描述主要用于服务器和基础设施开发周期一个周末项目描述常见技术栈Python FastAPI SQLite/DuckDB 静态前端支持平台Linux 服务器开发机 Windows/macOS 均可是否支持 API支持HTTP JSON 接口是否支持批量任务可通过批量脚本或接口循环实现显存要求不需要 GPU纯 CPU 应用注意一点标题里的 10 美元和周末开发周期决定了这类项目的核心原则是“轻”。轻量存储、轻量服务、轻量前端任何需要单独维护集群的组件都不在考虑范围内。2. 适用场景与使用边界这个工具到底适合谁从我的角度理解它主要服务以下几类场景独立开发者在产品立项时快速生成域名候选不用一个后缀一个后缀去注册商页面验证。内容站或 SEO 团队批量筛选与品牌词相关的域名做竞品词和长尾词调研。域名投资收藏者建立自己的本地域名库按关键词和长度检索稀有域名。需要在离线环境批量检查域名记录的运维或运营人员。它能解决的问题也很明确一次性导入 50 万条记录后续搜索都是在本地完成响应速度远快于挨个查询注册商把搜索封装成 API 后可以进一步接到品牌命名工具、落地页生成器或者聊天机器人里总体维护成本低放在个人服务器上不会产生额外负担。但使用边界同样要讲清楚它不是通用的互联网搜索引警不能对标 Google 或 Bing只能搜索你已经收集到的域名数据。它不负责实时 whois 查询。数据库里的注册状态是历史的不能替代注册商实时结果。它不能作为域名交易、商标注册、法律纠纷的唯一判断依据最终确认必须回到注册局或注册商页面。如果数据集来源不合法或者工具被用于批量抢注和恶意扫描会带来明显的合规风险。合规是这个项目最需要注意的部分尤其是 whois 数据里面可能包含注册人的个人信息。在多数地区批量抓取和展示 whois 个人信息会触碰隐私保护规则。更稳妥的做法是只保留“该域名是否处于已注册状态”这样的结果而不是把注册人、邮箱、电话等字段都存档展示。3. 数据准备与合规采集50 万条域名记录不是凭空长出来的数据来源和清洗链路是整个项目的地基。选错数据源后面搜索再好也没有用。3.1 公开域名数据源常见合法来源有这几种证书透明度日志Certificate Transparency LogsHTTPS 证书在签发时会写入公开日志日志里包含大量域名字段。通过解析 CT 日志可以批量提取域名再经过去重和字段清洗得到可用列表。Common Crawl 公开爬取数据定期发布的互联网网页快照数据里面包含海量 URL提取域名后可以补充很多长尾站点记录。注册局公开列表部分 TLD 的注册局会提供 zone file 访问权限但申请门槛因注册局而异而且不是所有后缀都能拿到。能拿到的前提下这是最权威的数据源之一。这类外部数据源的共同问题是原始文件巨大需要做大量过滤。比较好的处理流程是先解析原始数据去掉端口号、路径、协议前缀再统一域名格式最后按主域名维度去重。3.2 自建爬虫的边界如果不想完全依赖外部列表也可以写受限爬虫从公开网页链接中提取域名。但这里有两个明确边界一是遵守目标网站的 robots 协议和访问频率不能对注册商、whois 服务做高强度请求二是不要做大范围端口扫描和子域名爆破这类行为容易引发安全和法律问题。一个周末时间要完成 50 万条数据收集建议优先用公开数据集爬虫只做补充。3.3 数据清洗字段拿到原始域名列表后按以下规则做清洗去除重复项。过滤空域名和含非法字符的记录。决定是否要保留子域名。域名搜索工具一般只保留注册主域名即example.com而不是sub.example.com这样搜索“example”时结果更干净。提取 TLD 后缀、域名裸名、域名长度、是否数字域名、是否含连字符等特征字段。给每条记录标记数据来源和更新时间便于后续增量更新。3.4 存储字段设计建议按这种结构建表字段说明id主键domain完整域名如 example.comname裸域名如 exampletld后缀如 com、net、xyzlength域名长度可用来快速找短域名has_hyphen是否含连字符has_digit是否含数字status注册状态备注可留空source数据来源updated_at更新时间这里再强调一次不要保存不必要的 whois 个人字段。只存“域名是否存在”这样的布尔或枚举状态就能满足大多数搜索场景。4. 技术选型与系统设计50 万条记录是个很微妙的规模。它不能用 Excel 直接打开但也完全不需要分布式搜索引擎。从 10 美元预算和周末开发的约束来看技术选型核心就三个字不折腾。4.1 可选存储方案对比SQLite FTS5 是一个很自然的选项。SQLite 自带全文搜索扩展 FTS550 万条文本数据对它来说压力不大数据库就是一个单文件备份、迁移、部署都非常简单。缺点是 FTS5 的分词和 MATCH 语法需要一些学习成本而且不太适合复杂的分词场景但对域名这种前缀/后缀特征明显的文本来说足够了。DuckDB 适合做分析型查询列式存储、导入 CSV 很快适合一次性批量过滤和导出比如“找出所有 .io 后缀且长度小于 6 的域名”。缺点是需要额外安装 Python 包不适合高频点查场景。PostgreSQL pg_trgm 能做模糊匹配功能很强但对一台 512MB 内存的便宜 VPS 来说维护成本偏高不建议作为首选。综合来看如果是自己搭这类工具优先考虑 SQLite FTS5或者更朴素的 SQLite 普通索引。FTS5 性能更好普通索引更适合快速上线。4.2 系统架构建议一个最小可运行的架构分成四层data/source.csv 原始域名数据 data/domains.db SQLite 数据库 app/main.py FastAPI 服务入口 app/search.py 搜索逻辑 app/update.py 数据更新脚本 static/index.html 搜索页面服务层用 FastAPI前端用纯静态 HTML数据层用 SQLite。整条链路上没有消息队列、没有 Redis、没有容器编排。这套设计在 10 美元预算下是合理的。5. 环境准备与开发环境搭建先看环境要求。这个项目不依赖 GPU纯 CPU 应用服务器成本可以压得很低。5.1 推荐环境操作系统Ubuntu 22.04 或 24.04开发机用 macOS、Windows 都可以。Python3.10 及以上。磁盘数据库文件加原始 CSV预留 1GB 足够。内存512MB 到 1GB 的 VPS 可以跑搜索是轻量操作。数据库SQLite 自带不需要额外安装服务。5.2 初始化项目mkdir domain-search cd domain-search python3 -m venv venv source venv/bin/activate pip install fastapi uvicorn如果使用 DuckDB再装一个依赖pip install duckdb5.3 目录结构domain-search/ ├── data/ │ ├── domains.csv │ └── domains.db ├── app/ │ ├── __init__.py │ ├── main.py │ ├── search.py │ └── update.py ├── static/ │ └── index.html ├── requirements.txt └── README.md6. 核心功能实现域名导入与搜索这一章给出核心代码模板。实际项目可能有差异但整体思路是通用的。6.1 建表打开 SQLite创建域名表CREATE TABLE IF NOT EXISTS domains ( id INTEGER PRIMARY KEY AUTOINCREMENT, domain TEXT NOT NULL UNIQUE, name TEXT NOT NULL, tld TEXT NOT NULL, length INTEGER NOT NULL, has_hyphen INTEGER DEFAULT 0, has_digit INTEGER DEFAULT 0, status TEXT, source TEXT, updated_at TEXT ); CREATE INDEX IF NOT EXISTS idx_domains_tld ON domains(tld); CREATE INDEX IF NOT EXISTS idx_domains_length ON domains(length);6.2 导入 50 万条域名数据假设数据文件是 CSV 格式每行一个域名domain example.com notely.xyz导入脚本app/update.pyimport csv import sqlite3 from pathlib import Path DB_PATH Path(data/domains.db) CSV_PATH Path(data/domains.csv) def normalize_domain(line: str) - str: line line.strip().lower() if not line or line.startswith(#): return None return line.rstrip(.) def main(): conn sqlite3.connect(DB_PATH) cur conn.cursor() with open(CSV_PATH, r, encodingutf-8) as f: reader csv.DictReader(f) rows [] for row in reader: domain normalize_domain(row.get(domain, )) if not domain or . not in domain: continue parts domain.split(.) name ..join(parts[:-1]) tld_part parts[-1] rows.append(( domain, name, tld_part, len(name), 1 if - in name else 0, 1 if any(ch.isdigit() for ch in name) else 0, unknown, public-list, 2025-06-01 )) if len(rows) 5000: cur.executemany( INSERT OR IGNORE INTO domains (domain, name, tld, length, has_hyphen, has_digit, status, source, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?), rows ) conn.commit() rows [] if rows: cur.executemany( INSERT OR IGNORE INTO domains (domain, name, tld, length, has_hyphen, has_digit, status, source, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?), rows ) conn.commit() cur.execute(SELECT COUNT(*) FROM domains) print(total:, cur.fetchone()[0]) conn.close() if __name__ __main__: main()批量写入 5000 条一次提交避免 50 万行逐条 insert 导致速度过慢。INSERT OR IGNORE配合唯一约束可以天然去重重复导入不会产生脏数据。6.3 搜索逻辑先实现最基础的两个搜索维度前缀搜索输入note返回note.com、notely.xyz等结果。包含搜索输入note返回所有域名裸名里包含 note 的记录。TLD 过滤只搜.com或.io。长度过滤短域名优先。搜索模块app/search.pyimport sqlite3 from pathlib import Path DB_PATH Path(data/domains.db) def search_domains(keyword: str, tld: str , limit: int 50): if not keyword: return [] conn sqlite3.connect(DB_PATH) conn.row_factory sqlite3.Row cur conn.cursor() sql SELECT domain, tld, length, status FROM domains WHERE name ? OR name LIKE ? params [keyword, f{keyword}%] if tld: sql AND tld ? params.append(tld) sql ORDER BY length ASC, domain ASC LIMIT ? params.append(limit) cur.execute(sql, params) rows [dict(r) for r in cur.fetchall()] conn.close() return rows50 万条数据下LIKE note%不一定能走标准索引实际响应时间需要在本机测试。如果单次查询能在几百毫秒内返回对个人工具完全够用如果等不了就给name字段建 FTS5 全文索引。FTS5 建表CREATE VIRTUAL TABLE domains_fts USING fts5( domain, name, tld, contentdomains, content_rowidid ); INSERT INTO domains_fts(rowid, domain, name, tld) SELECT id, domain, name, tld FROM domains;搜索时改用SELECT domain, tld FROM domains WHERE id IN ( SELECT rowid FROM domains_fts WHERE name MATCH note* )FTS5 的 MATCH 语法对点号等字符的处理比较特殊正式使用前建议先在一千条小数据集上验证避免匹配结果不符合预期。7. 搜索引警接口 API 与批量查询工具做成以后最有扩展价值的一步是暴露 HTTP API。这样前端可以调用脚本可以调用后续接聊天机器人也可以调用。7.1 FastAPI 接口app/main.pyfrom fastapi import FastAPI, Query from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from search import search_domains app FastAPI(titleDomain Search API) app.add_middleware( CORSMiddleware, allow_origins[*], allow_methods[*], allow_headers[*], ) class SearchRequest(BaseModel): keyword: str tld: str limit: int 50 app.get(/api/search) def api_search( keyword: str Query(..., description搜索关键词), tld: str Query(, descriptionTLD 后缀例如 com), limit: int Query(50, ge1, le100) ): results search_domains(keyword, tldtld, limitlimit) return { code: 0, message: ok, data: results } app.post(/api/search) def api_search_post(req: SearchRequest): results search_domains(req.keyword, tldreq.tld, limitreq.limit) return { code: 0, message: ok, data: results } app.get(/health) def health(): return {status: up}启动服务uvicorn app.main:app --host 127.0.0.1 --port 8000启动后浏览器直接访问http://127.0.0.1:8000/api/search?keywordnotetldio7.2 curl 调用curl http://127.0.0.1:8000/api/search?keywordnotetldiolimit10返回结构{ code: 0, message: ok, data: [ { domain: note.io, tld: io, length: 4, status: unknown } ] }7.3 Python 批量查询脚本如果要把域名搜索接到批量流程里比如一次性跑几千个关键词建议写一个脚本控制并发和限速import requests import time import json BASE_URL http://127.0.0.1:8000 def batch_search(keywords, tld, outputresults.jsonl): results [] for kw in keywords: try: resp requests.get( f{BASE_URL}/api/search, params{keyword: kw, tld: tld, limit: 20}, timeout5 ) if resp.status_code 200: data resp.json().get(data, []) results.append({keyword: kw, results: data}) else: results.append({keyword: kw, error: resp.status_code}) except Exception as e: results.append({keyword: kw, error: str(e)}) time.sleep(0.2) # 限速避免打满服务 with open(output, w, encodingutf-8) as f: for item in results: f.write(json.dumps(item, ensure_asciiFalse) \n) print(done, total:, len(results)) if __name__ __main__: kws [note, memo, planner, pixel, drift] batch_search(kws)批量任务里最容易被忽略的是失败重试。接口偶尔会因为网络抖动或资源占用返回 5xx建议在脚本里加 retry 逻辑遇到超时或 500等 1 秒后再试一次连续失败则把错误写入日志而不是直接中断整个任务。7.4 接口安全建议如果服务要暴露到公网至少做三件事加访问令牌请求头里带Authorization: Bearer token。用限流中间件或 Nginx 层限制单 IP 请求频率。只开放需要公开的接口不需要的接口不要暴露。8. 部署上线与成本控制10 美元预算怎么分配核心原则是能白嫖就白嫖能用免费开源就不用商业服务能单文件就单文件。8.1 服务器选择这类项目对配置要求很低。常见选择是买一台便宜 Linux VPS1 核、1GB 内存、20GB 存储价格通常在每月几美元。如果你选择 1 核 512MB 的机器跑 FastAPI SQLite 也够用。前端部分可以用 Cloudflare Pages 或 GitHub Pages 免费托管进一步节省 VPS 带宽。8.2 使用 systemd 托管服务写一个 systemd 服务文件/etc/systemd/system/domain-search.service[Unit] DescriptionDomain Search API Afternetwork.target [Service] Userubuntu WorkingDirectory/home/ubuntu/domain-search ExecStart/home/ubuntu/domain-search/venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000 Restartalways RestartSec3 EnvironmentPYTHONUNBUFFERED1 [Install] WantedBymulti-user.target启用并启动sudo systemctl daemon-reload sudo systemctl enable domain-search sudo systemctl start domain-search查看日志sudo journalctl -u domain-search -f8.3 前端页面前端可以直接写一个静态页面用 Nginx 或 Caddy 反代到 API。简单示例static/index.html!DOCTYPE html html langzh-CN head meta charsetUTF-8 titleDomain Search/title /head body h1域名搜索/h1 input typetext idkw placeholder输入关键词如 note / select idtld
延伸阅读

更多相关文章

2026/10/24 18:04:04

诈骗电话识别机器学习项目复盘:从29779名到可落地的反诈模型

简介:机器学习在处理极端不平衡的分类任务时,常面临样本分布稀疏、指标失效、时间漂移等挑战。基于通话详单的特征工程,是区分正常通信与诈骗行为的关键——频次、时序、关系网络等维度能有效刻画异常模式。然而,若特征统计跨越未…

2026/10/24 17:09:04

Grok Bot 桌面端 DeepLink 插件:用链接直达操作,开启本地自动化

Grok Bot 桌面端上线了 DeepLink 插件。简单说,你现在可以用一条类似grokbot://...的链接,在桌面应用里直接触发 Grok Bot 的指定动作,比如新建对话、发送提示词、跳转到某个会话,或者把参数从外部传进去。以前要打开窗口、找入口…

2026/10/22 7:52:47

Grok Bot桌面端DeepLink插件:AI助手如何融入你的开发工作流

如果你是这两年才开始接触 AI 编程助手,大概会有一个明显感受:AI 能力早就不是“网页里开一个聊天窗口”那么简单了。尤其是最近一段时间,Claude Code、Codex、DeepSeek Harness 等桌面端工具接连出现,大家讨论的重点不再是“哪个…

2026/10/25 2:37:58

OpenClaw飞书机器人:智能对话引擎在企业协作中的应用

1. OpenClaw飞书机器人功能全景解析OpenClaw作为新一代智能对话引擎,在飞书平台实现了群聊与私聊双模式的无缝对接。这个开源项目最初由某科技团队在2023年推出,其核心价值在于将大语言模型的智能对话能力深度整合到企业协作场景中。我部署过不下二十个企…

2026/10/25 2:37:58

数据处理中的change_domain与reduce_domain操作详解

1. 理解change_domain与reduce_domain的核心概念在数据处理和计算领域,change_domain和reduce_domain是两个经常被提及但容易混淆的操作。我第一次接触这两个概念是在处理大规模地理空间数据集时,当时需要将高分辨率气象数据适配到不同分析尺度。change_…

2026/10/25 2:37:58

174把金钥匙连抽盲盒:抽卡概率与保底机制蒙特卡洛验证

最近在整理抽卡类小游戏的概率验证流程时,被一个很实际的问题反复问到:仓库里攒了一百多把钥匙,一次性全抽掉到底划不划算,会不会一路黑到吃满保底?这篇就借"174 把金钥匙连抽新盲盒"这个具体场景&#xff0…

2026/10/25 2:37:58

1024手写Shell:拼写建议、信号处理与执行边界

终端里把grep敲成gerp,程序可以猜一个相似单词,却不能据此断定用户想做什么。这个差别很小,也很容易被“智能Shell”四个字盖过去。 这次只做一个窄原型:按空白拆参数,启动一个前台子进程,等待它退出&…

2026/10/25 2:32:58

Hadoop核心架构解析:HDFS、YARN与MapReduce协同原理

1. Hadoop核心架构解析:三驾马车如何协同工作?在大数据领域摸爬滚打多年,我见过太多初学者面对Hadoop时一脸茫然的样子。这个2006年诞生的分布式系统框架,如今已成为企业级数据处理的标配工具。但很多人对它的理解停留在"Had…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑