纯 Python 标准库实现,零第三方依赖。 一个 SQLite 文件即全部数据。
做注册和药事管理,最耗时的不是理解法规,而是找到并确认法规:某条要求出自哪份 文件?现行有效还是已被替代?某个 ICH 指导原则在国内是否已适用?三年前那份公告和现在 的版本差在哪?通用搜索引擎做不到「按发文字号精确检索」「只看现行有效」「比对两个 版本」。本项目把这件事变成一个可以离线运行、数据完全自持的库。
能做什么
| 能力 | 说明 |
|---|---|
| 全文检索 | SQLite FTS5 trigram 索引;中文两字词自动回退 LIKE,不会出现「搜不到」 |
| 检索语法 | 药品注册 -化妆品(排除)、"精确短语"、多词隐式 AND |
| ICH / CTD 自动归类 | 按 ICH 编号(Q1–Q12、S1–S11、E1–E14、M1–M8)与 CTD 模块归类 |
| 主题分类 | 药品注册 / 药物警戒 / 药品生产 / 价格与采购 / 中医药 等 18 类 |
| 发文字号归一化 | 药监局公告2021年第32号 → 国药监〔2021〕32号,同一文件只有一个标识 |
| 版本追踪与 diff | 正文变化时自动归档旧版本,输出 unified diff,可定位到具体条款 |
| 效力状态推断 | 从正文尾部识别「自…起施行」/「起废止」,保守标注 |
| 本地导入 | HTML / PDF / TXT / Markdown 拖入即入库,保留来源路径便于审计 |
| Web 界面 | 零依赖 http.server 实现,支持分面筛选与文档阅读 |
实测数据
在中国政府网政策文件库真实数据上的验证结果(4 组关键词 × 1 页):
库中共 62 份文件,16 个标签
主题分布 中医药 25 · 药品注册 10 · 药品生产 8 · 化妆品 6 · 价格与采购 5 · 药物警戒 5
发文机关 国家药品监督管理局 27 · 国务院办公厅 9 · 国务院 8
年份跨度 2019 – 2026
效力状态 现行有效 16 · 已废止 6 · 未标注 40
快速开始
git clone https://github.com/leerogerstheman/NMPARegHub
cd NMPARegHub
python regkb.py crawl # 采集中国政府网药品法规
python regkb.py import D:\我的法规资料 # 导入本地公告(HTML/PDF/TXT/MD)
python regkb.py search "药品注册 -化妆品" # 检索
python regkb.py facets # 分面统计
python regkb.py diff 11 # 比对版本
python webui.py # Web 界面 → http://127.0.0.1:8765
环境要求:Python 3.9+。不需要 pip install 任何东西。
数据来源与合规说明
nmpa.gov.cn、cde.org.cn、nhc.gov.cn 均部署 JavaScript 反爬验证(阿里云盾 WAF),
对普通 HTTP 客户端返回 HTTP 412/202 与一段混淆的挑战脚本,必须执行该脚本生成签名
Cookie 才能访问。
本项目不实现绕过该保护机制。 绕过网站明确部署的安全控制,既违背站点所有者的
意愿,也不适合出现在一个以合规为主题的作品里。这些机构的文件通过离线导入进入
知识库 —— 在浏览器中正常打开并另存,再用 import 命令入库,这是完全合规且可审计
的路径,导入时会记录来源文件路径。
| 来源 | 状态 |
|---|---|
中国政府网政策文件库 gov.cn | 自动采集(公开 JSON 检索接口 + 服务端渲染文章页) |
国家药典委员会 chp.org.cn | 自动采集 |
| NMPA / CDE / 卫健委 | 离线导入(见上) |
| 本地文件 | 离线导入,支持 HTML / PDF / TXT / MD |
开发中由真实数据暴露的三个缺陷
这三个 bug 都不是想出来的,是跑真实数据跑出来的,均有回归测试覆盖:
- 纯排除查询静默返回 0 条 ——
doc_number NOT LIKE ?在字段为 NULL 时结果为 NULL,而NULL AND x永不为真,导致所有无发文字号的文件被静默丢弃。用COALESCE包裹修复。这类 bug 在生产环境可以潜伏很久。 - FTS5 的
NOT无法独立成立 —— 纯排除查询在 FTS 中恒为空,排除条件改用 SQL 谓词实现。 - 分类子串误匹配 —— 「化妆品注册备案」因含「注册」被误归为「药品注册」, 引入标题级排除规则修复。
设计取舍
为什么用规则分类而不是模型? 注册专员需要知道某份文件为什么被归到某一类。 关键词表可审计、可复现、可解释;不透明的分类器三者皆无。每个标签都能追溯到正文中 的字面匹配。
为什么保留历史版本? 重复采集时静默覆盖正文,恰好会摧毁合规用户最关心的信息 —— 法规什么时候改了什么。
为什么效力状态标注保守? 把一份现行有效的法规误标为「已废止」,比留成
unknown 危害大得多,所以只在正文尾部出现明确废止表述时才标注。
测试
python tests/test_regkb.py # 22/22 passed
覆盖发文字号解析(含反例)、归类排除规则、效力推断、FTS 索引同步、检索语义 (含纯排除查询与两字词回退)、版本归档与 diff。
局限
- 分类规则是启发式的,不是法律意见。标签用于辅助检索,不能替代对原文的阅读。
- 效力状态为推断值,来源页面通常不提供结构化的废止标记。
- gov.cn 收录范围有限:主要收录国务院及部门层面文件,NMPA 的大量技术指导原则 并不在其中,这是需要离线导入的原因。
- 本项目不是法律依据,正式注册申报请以官方发布文本为准。