把个人豆瓣的在读、想读、读过、在看、想看和看过记录同步到 MySQL,封面上传到七牛云 Kodo, 并通过每页 20 条的 API 在网页中无限滚动展示。
- Node.js 18.17+
- MySQL 5.5+(推荐使用仍受支持的 MySQL 8.x)
- 七牛云 Kodo 空间和已绑定的 HTTPS 域名
-
安装依赖:
pnpm install
-
编辑项目中已有的
.env,填写 MySQL、豆瓣和七牛配置。 -
初始化数据库:
pnpm db:init
-
首次同步:
pnpm sync
-
启动网站:
pnpm start
访问 .env 中 PORT 对应的地址,例如 Docker 配置使用
http://127.0.0.1:3006。
DOUBAN_USER_ID 是个人主页地址里的用户 ID:
https://www.douban.com/people/这里是用户ID/
公开可见的列表通常可以留空 DOUBAN_COOKIE。如果页面需要登录,在浏览器登录豆瓣后,
从开发者工具的网络请求中复制 Cookie 到 .env。不要把 .env 提交到 Git。
QINIU_ZONE 默认使用 auto 自动查询 Bucket 区域,也可以手动填写:
| 值 | 区域 |
|---|---|
auto |
自动查询 |
z0 |
华东 |
z1 |
华北 |
z2 |
华南 |
na0 |
北美 |
as0 |
东南亚 |
如果暂时没有填写完整的七牛配置,文字数据仍会同步到 MySQL,但页面不会显示封面。
手动同步:
pnpm sync生产环境默认关闭 HTTP 同步接口。Docker 部署时使用:
docker compose exec douban-api pnpm sync只有在确实需要远程触发时,才设置:
ENABLE_HTTP_SYNC=true
SYNC_TOKEN=至少32字节的随机值随后必须通过 x-sync-token 请求头访问 /api/sync 和
/api/sync/status。生产环境还应在 Nginx 层增加 IP 白名单或身份代理和
请求限流。详细要求参见 SECURITY.md。
生产环境建议用 cron 每天运行一次:
15 3 * * * cd /path/to/db-data && /path/to/pnpm sync >> sync.log 2>&1GET /api/items?type=book&status=do&page=1
GET /api/items?type=book&status=wish&page=1
GET /api/items?type=book&status=collect&page=1
GET /api/items?type=movie&status=do&page=1
GET /api/items?type=movie&status=wish&page=1
GET /api/items?type=movie&status=collect&page=1
GET /api/counts
GET /api/health
/api/items 返回的每条记录还包含以下评分字段:
{
"userRating": 5,
"doubanRating": 8.7,
"doubanRatingCount": 123456
}没有评分时返回 null。userRating 是个人 1-5 星评分,
doubanRating 是豆瓣 0-10 分,doubanRatingCount 是豆瓣评分人数。
执行 pnpm db:init 完成旧表迁移,再执行 pnpm sync 即可为已有记录补齐评分。
其中:
type:book或moviestatus:do、wish或collectpage: 从 1 开始- 每页固定返回 20 条
- 生产环境应执行
chmod 600 .env,并确保 MySQL 3306 不对公网开放。 PUBLIC_INCLUDE_NOTES默认是false,避免公开个人短评。- 仅在完整抓完一个分类后,程序才会标记该分类中已经删除的记录。
- Cookie 过期或出现验证码时同步会停止,已有数据库内容不受影响。
- 同步频率不要过高,建议每天一次。
- 豆瓣页面结构调整后,可能需要更新
src/douban-scraper.js中的选择器。 - 公开上线前应确认豆瓣内容及封面图片的使用授权。