抓取 Danbooru Tags API 的全部 tag,保存为本地 CSV, 支持断点续传、增量更新与全量刷新。匿名访问、按 1 请求/秒限速,2026-10 实测 184 万行约 31 分钟。
- 断点续传 —— ID 游标降序扫描(不用会被限死在 100 万条的偏移分页),每页 flush CSV 并原子写断点,Ctrl-C / 断网后重跑同一条命令接着抓。
- 增量更新 ——
hanatsumi update只抓上次之后新增的 tag,秒级完成。 - 全量刷新 ——
hanatsumi refresh全量重扫到暂存文件,真正到达底部才原子替换, 期间旧文件可正常读取;用于同步post_count、改名、废弃与删除。 - 校验恢复 ——
hanatsumi verify对账行数 / id 范围 / 坏行 / 重复 id,状态文件丢失可按 CSV 重建。
分页与限速的实测依据见 docs/api.md,完整设计(状态不变量、
update 与 refresh 的分工、日志与输出策略、退出码)见 docs/design.md。
安装
Python 3.10 及以上:
pip install hanatsumi
从源码(含开发工具 ruff / ty / pytest):
git clone git@github.com:licyk/temp.git && cd temp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
快速开始
hanatsumi fetch # 全量抓取:约 1837 页 / 31 分钟,随时 Ctrl-C,重跑同命令续传
hanatsumi status # 看断点与 CSV 概况
hanatsumi update # 之后每次同步新增的 tag(秒级)
hanatsumi refresh # 让 post_count / 改名 / 废弃 / 删除也同步进来(约 1 小时)
hanatsumi 装好后是独立命令;也可以用 python -m hanatsumi fetch。
命令行
hanatsumi
├── fetch [--out --state --delay --page-size --timeout --max-retries --max-pages -q]
├── update [同上] 增量抓取上次之后新增的 tag(需先全量完成)
├── refresh [同上] 全量重扫到暂存文件,成功后原子替换
├── status [--out --state] 查看断点状态与 CSV 概况
├── verify [--out --state --dups --init-state] 校验 CSV 与状态文件
├── reset [--out --state --yes] 删除 CSV、状态文件与暂存文件
└── version 显示版本与运行环境
抓取类命令(fetch / update / refresh)共用参数:
| 参数 | 默认 | 说明 |
|---|---|---|
--out |
data/tags.csv |
CSV 路径(状态文件默认同名 .state.json) |
--state |
由 --out 推导 |
显式指定状态文件 |
--delay |
1.0 |
请求最小间隔(秒),匿名建议 ≥ 1.0 |
--page-size |
1000 |
单页条数(1~1000,API 上限) |
--timeout |
30.0 |
单次请求超时(秒) |
--max-retries |
8 |
失败重试次数 |
--max-pages |
0 |
本次最多抓几页,0=不限(调试用) |
-q / --quiet |
关 | 不打印逐页进度 |
输出约定:逐页进度与日志在 stderr(不污染管道,日志等级带颜色),
status / verify / version 的表格在 stdout;--debug 在任何层级都可用。
[0:12] id 0% pages=13 rows=13,000 rate=1105/s cursor=2730104 eta=41:20 ← stderr,原地刷新
INFO 完成(max_pages):pages=13 fetched=13,000 written=13,000 … ← stderr,日志
INFO 状态:rows=13,000 range=[2730104, 2743978] complete=False
INFO CSV:data/tags.csv
进度行里的 id NN% 是精确进度(已扫过的 id 区间占比,游标降到数据集底部即 100%);
eta= 是估算值,口径分两层:refresh 用上一次快照的行数当总数(行口径,很准),
全新 fetch 只能按 id 区间线性外推(id 口径,偏保守)—— Danbooru 不提供总数,
且 id 密度极不均匀(实测 4%~96%),详见 docs/design.md。
输出文件
| 文件 | 内容 |
|---|---|
data/tags.csv |
UTF-8(新建时写 BOM,Excel 可直接打开),8 列:id, name, post_count, category, is_deprecated, created_at, updated_at, words |
data/tags.state.json |
断点状态:min_id 续传游标、max_id 增量下界、rows 行数、complete 是否全量完成 |
data/tags.new.csv / .state.json |
refresh 的暂存文件,只在刷新期间存在,reset --yes 一并清理 |
数据源更新了怎么办
| 你要同步的变化 | 命令 | 耗时 |
|---|---|---|
| 新增 tag | hanatsumi update |
秒级 |
post_count 变化、改名、废弃、tag 被删除 |
hanatsumi refresh |
约 1 小时 |
update 只追加新 id,无法发现已有行的字段变化(Danbooru 不支持按更新时间过滤,
见 docs/api.md),所以需要准确 post_count 时跑 refresh;
推荐节奏:每天 update,每周 refresh。刷新完成后再跑一次 update 可补齐刷新期间新建的 tag。
故障恢复
| 情况 | 处理 |
|---|---|
| 中途 Ctrl-C / 断网 | 直接重跑 hanatsumi fetch(自动续传) |
| 状态文件丢失 / 损坏 | hanatsumi verify --init-state 后再 fetch(从 CSV 最小 id 续扫到底) |
| 疑似数据不一致 | hanatsumi verify --dups(行数 / id 范围 / 坏行 / 重复 id 全面对账) |
refresh 中断 |
重跑 hanatsumi refresh(续跑暂存文件,正式文件不受影响) |
refresh 暂存状态丢失 |
重跑 refresh 会按 tags.new.csv 自动重建状态并续跑 |
| 从头再来 | hanatsumi reset --yes(连暂存文件一起清理) |
开发
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
python -m pytest -q # 30 个离线用例
python -m ruff check hanatsumi tests # lint
python -m ruff format --check hanatsumi tests
python -m ty check hanatsumi # 类型检查(自动发现 .venv)
许可证
GPL-3.0
Metadata
Release files for hanatsumi 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hanatsumi-0.1.1.tar.gz | 47.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hanatsumi-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 92.2 kB
Release files / hanatsumi-0.1.1.tar.gz
| Download URL | hanatsumi-0.1.1.tar.gz |
|---|---|
| Size | 47.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9dab7e87cebf90cf3b40bc97c47a4553eb29e99351bdf354181ea7e6e2e591ee
|
|
BLAKE2b-256 checksum How to use checksums |
4bba2d48aa0a2817f770eb4937294d79b4fd1f9ab369894f05ef84c4719f878d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|
Release files / hanatsumi-0.1.1-py3-none-any.whl
| Download URL | hanatsumi-0.1.1-py3-none-any.whl |
|---|---|
| Size | 45.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
29dcaf089e201c9cd36ef24f397d8c8faabb7f9e983a51e9dc1fbaa0e5913632
|
|
BLAKE2b-256 checksum How to use checksums |
276a64baebc31556a68e68d22a904d753ed1fd65b5a79f0aa611a5d11279a94c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|