使用python爬虫爬取Confluence页面保存到本地

# Confluence Wiki 本地备份工具

这个工具从配置文件读取参数,登录Confluence Wiki 后,从指定 `root_page_id` 开始递归保存页面树。输出会尽量保持 Confluence 原页面效果,并按左侧树结构创建本地文件夹。

参数优先级是:命令行参数 > `config.json`。所以开多个 PowerShell 窗口时,可以只在命令行传不同的 `--root-page-id`。

## 1. 安装依赖

```powershell
cd wiki_py
pip install -r requirements.txt
```

## 2. 修改配置

打开项目目录下的 `config.json`,主要改这里:

```json
{
"base_url": "https://wiki.yours.com",
"root_page_id": "012345678",
"output": "wiki_backup",
"max_pages": 3,
"clean_output": false,
"delay": 0.2,
"request_timeout_seconds": 60,
"login_timeout_seconds": 120,
"request_retries": 3,
"auth": {
"username": "你的Wiki用户名",
"password": "",
"cookie": "",
"cookie_jar": ".confluence_cookies.txt"
}
}
```

建议 `password` 留空。运行时 PowerShell 会提示输入密码,不会把密码写到文件里。

`cookie_jar` 用于保存登录后的 Cookie。第一次登录成功后,后续窗口会优先复用它,减少重复登录导致的超时。

## 3. 先测试 3 个页面

配置里现在默认是:

```json
"max_pages": 3
```

运行:

```powershell
python confluence_backup.py
```

也可以在命令行临时指定根页面:

```powershell
python confluence_backup.py --root-page-id 135792468
```

## 4. 全量备份

确认能抓到子页面后,把 `config.json` 里的:

```json
"max_pages": 3
```

改成:

```json
"max_pages": null
```

再运行:

```powershell
python confluence_backup.py
```

## 5. 多个窗口同时爬取

建议先开一个窗口登录一次,生成 Cookie 缓存:

```powershell
python confluence_backup.py --root-page-id 135792468 --max-pages 1
```

看到 `Saved cookie cache` 后,再开多个窗口同时爬。

`config.json` 里的 `output` 表示总备份目录:

```json
"output": "wiki_backup"
```

脚本会先读取根页面标题,再自动保存到类似 `wiki_backup\统一预约_135792468` 的目录。每个窗口只要传不同的根页面 ID,就会自动保存到不同目录:

```powershell
python confluence_backup.py --root-page-id 1357924681 --max-pages 0
python confluence_backup.py --root-page-id 1357924682 --max-pages 0
python confluence_backup.py --root-page-id 1357924683 --max-pages 0
```

`--max-pages 0` 表示不限制页数。

## 6. 重新爬取并清理旧数据

如果之前目录结构错了、附件重复了,重新跑时带上 `--clean`:

```powershell
python confluence_backup.py --root-page-id 135792468 --max-pages 0 --clean
```

如果某个目录没有 `tree.json`,一般说明上次中途失败,是半成品目录,也建议带 `--clean` 重新爬。

`--clean` 只会清理脚本生成的这些内容:

```text
_assets
_debug
index.html
tree.html
tree.json
raw.html
metadata.json
assets
attachments
```

不会删除整个输出目录里的其他文件。

如果只想先清掉某个错误输出目录,不重新爬:

```powershell
python confluence_backup.py --root-page-id 135792468 --clean-only
```

如果旧数据在以前手动指定的目录里,也可以指定旧目录:

```powershell
python confluence_backup.py --root-page-id 135792468 --output "wiki_backup\统一预约_135792468" --clean-only
```

## 7. 手动删除多余目录后重建 tree.html

如果你发现某些页面目录爬多了,可以先在文件夹里手动删除对应的页面文件夹,然后运行:

```powershell
python confluence_backup.py --output "wiki_backup\统一预约_135792468" --rebuild-tree-only
```

如果想对整个 `wiki_backup` 下面的所有根目录都重新整理:

```powershell
python confluence_backup.py --output "wiki_backup" --rebuild-tree-only
```

如果只想在某个本地子目录下面新生成这个子目录自己的 `tree.html/tree.json`:

```powershell
python confluence_backup.py --tree-dir "wiki_backup\统一预约_135792468\设计方案_1357924681"
```

这个命令只读取指定目录及其子目录下面现有的 `metadata.json`,不会联网,也不会爬取新页面。

这个命令只读取本地现有的 `metadata.json` 和 `index.html`,不会重新爬 Wiki。新版 `tree.html` 支持逐级展开、收起,也支持全部展开、全部收起。

## 8. 增量补漏和更新时间同步

如果发现少量页面没有爬下来,可以用补漏模式:

```powershell
python confluence_backup.py --root-page-id 135792468--incremental
```

`--incremental` 只补本地缺失的 pageId。已有页面不会因为更新时间被覆盖。

如果只想检查远程页面是否更新,可以用更新时间同步模式:

```powershell
python confluence_backup.py --root-page-id 135792468--check-updates
```

`--check-updates` 会比较远程和本地页面顶部的“最后更新于 YYYY-MM-DD”。远程日期更晚时重新保存该页面;日期一致时跳过页面正文。

两个功能可以同时使用:

```powershell
python confluence_backup.py --root-page-id 135792468--incremental --check-updates
```

这样会同时补缺失页面,并覆盖远程更新过的已有页面。

新增页面清单会保存在当前根目录的 `_reports` 下,同时生成 JSON 和 CSV:

```text
_reports\incremental_new_pages_YYYYMMDD_HHMMSS.json
_reports\incremental_new_pages_YYYYMMDD_HHMMSS.csv
```

清单里包含 `title`、`page_id`、`parent_id`、`source_url`、`local_index`,方便核对本次补了哪些页面。

被远程新版本覆盖更新的页面会另外记录在:

```text
_reports\incremental_updated_pages_YYYYMMDD_HHMMSS.json
_reports\incremental_updated_pages_YYYYMMDD_HHMMSS.csv
```

清单里包含 `title`、`page_id`、`old_updated_at`、`new_updated_at`、`source_url`、`local_index`。

如果只想先试补 3 个缺失页面:

```powershell
python confluence_backup.py --root-page-id 135792468--incremental --max-pages 3
```

如果大目录不动,只想补某个子目录下面缺失的页面,可以同时传大目录 pageId 和子目录 pageId:

```powershell
python confluence_backup.py --root-page-id 1357924681--subtree-page-id 64292956 --incremental
python confluence_backup.py --root-page-id 1357924681--subtree-page-id 64292956 --check-updates
python confluence_backup.py --root-page-id 1357924681--subtree-page-id 64292956 --incremental --check-updates
```

这里 `--root-page-id` 用来定位已有的大目录,`--subtree-page-id` 用来指定只检查哪个子目录。脚本会先确认子目录 pageId 是否属于这个大目录树;如果不属于,会提示并停止,不会新增或覆盖页面。

## 9. 输出结构

```text
wiki_backup\统一预约_135792468
├─ index.html 根页面正文
├─ tree.html 树形索引
├─ tree.json 页面树数据
├─ _assets Confluence 公共 CSS、JS、图标、字体等
├─ _debug 页面树接口调试文件
├─ raw.html 根页面原始 HTML
├─ metadata.json 根页面元数据
├─ assets 根页面图片、媒体等
├─ attachments 根页面附件
└─ 子页面标题_pageId
├─ index.html
├─ raw.html
├─ metadata.json
├─ assets
└─ attachments
```

`wiki_backup\_page_map` 是多个窗口共享的 pageId 到本地页面路径映射,用于把跨目录链接改成本地相对路径。

## 10. 附件重复下载

新版脚本已经把附件下载改成按“页面 + 附件路径/文件名”去重。同一个页面里正文链接和附件列表都指向同一个文件时,只会保存一份。

## 11. 目录结构和原网站不一致怎么办

新版默认只使用 Confluence 的直属子页面接口,不再从左侧侧边栏 HTML 里猜子页面。这样可以避免把祖先、兄弟目录或旁支页面挂到当前页面下面。

## 12. 仍然只保存一个页面怎么办

先看运行输出里是否出现:

```text
Found N child page(s).
```

如果还是 `No child pages found for this page.`,看下面目录里的文件:

```text
wiki_backup\统一预约_135792468\_debug
```

这里会保存页面树接口返回内容.

## 13. 其他说明

如果 Wiki 使用验证码、短信、企业微信扫码或 SSO,账号密码直登可能会失败。这种情况下还是需要 Cookie,或者用浏览器自动化登录方案。

如果登录接口偶尔超时,可以把配置里的 `login_timeout_seconds` 调大,例如 180;如果页面或附件下载慢,可以把 `request_timeout_seconds` 调大。

posted @ 2026-09-05 22:05  请叫我小马驹  阅读(9)  评论(0)    收藏  举报