name: pdf-page-extract description: 从PDF页面提取丰富数据,包括带元数据的文本片段、渲染的PNG图像和页面映射。为下游处理创建持久化工件。
PDF页面提取技能
目的
此技能从PDF页面提取所有必要数据,以实现准确的AI驱动HTML生成。它产生三个关键工件:
- 丰富提取数据 - 带字体元数据(大小、样式、位置)的文本片段
- 渲染的PNG图像 - 供AI理解页面布局的视觉参考
- 页面映射 - PDF索引到书籍页面的权威映射
这是整个流程的确定性、基于Python的基础。所有提取的数据都保存到持久化文件中,以便追溯和未来处理。
操作步骤
-
验证输入参数
- 检查PDF文件是否存在且可读
- 验证页面范围(PDF索引或书籍页面)
- 确认输出目录结构
-
建立页面映射(如果尚未完成)
- 运行:
python3 Calypso/tools/read_page_footers.py - 扫描页面页脚以建立PDF索引→书籍页面映射
- 保存到:
analysis/page_mapping.json
- 运行:
-
使用PyMuPDF和pdfplumber提取丰富页面数据
- 运行:
python3 Calypso/tools/rich_extractor.py - 提取带字体元数据的文本片段:
- 字体名称和大小
- 粗体/斜体标志
- 位置(边界框)
- 颜色信息
- 分析页面结构以识别:
- 可能的标题(通过大小和样式)
- 段落(常规文本)
- 潜在列表
- 使用pdfplumber检测表格
- 保存到:
analysis/chapter_XX/rich_extraction.json
- 运行:
-
将PDF页面渲染为PNG
- 将页面转换为高分辨率PNG图像(300+ DPI)
- 保持视觉保真度以供AI参考
- 保存到:
output/chapter_XX/page_artifacts/page_YY/02_page_XX.png
-
提取嵌入图像(如果存在)
- 运行:
python3 Calypso/tools/extract_images.py - 从页面提取所有图像
- 保存:
output/chapter_XX/images/page_YY_image_*.png - 创建元数据:
page_YY_images.json
- 运行:
-
验证提取完整性
- 验证所有文件是否正确保存
- 检查JSON文件是否有效
- 确认PNG图像可读
- 验证页面映射一致性
输入参数
chapter: <int> - 章节编号(1-8)
start_page: <int> - 起始PDF索引(从0开始)或页面范围
end_page: <int> - 结束PDF索引(如果是单页则为可选)
pdf_path: <str> - PDF文件路径(默认:Calypso/PREP-AL 4th Ed 9-26-25.pdf)
output_base: <str> - 输出目录(默认:Calypso/output)
mapping_file: <str> - 页面映射文件(默认:Calypso/analysis/page_mapping.json)
输出结构
保存的工件文件
每页工件(位于output/chapter_XX/page_artifacts/page_YY/):
01_rich_extraction.json- 带元数据的文本片段02_page_XX.png- 渲染的PDF页面图像page_mapping.json- 共享映射文件(符号链接或副本)
提取数据(位于analysis/chapter_XX/):
rich_extraction.json- 章节中所有页面的完整提取page_6_pattern_analysis.json- (可选)特定页面的模式分析
图像(位于output/chapter_XX/images/chapter_XX/):
page_XX_image_*.png- 页面中的嵌入图像page_XX_images.json- 嵌入图像的元数据
丰富提取JSON格式
{
"page_number": 16,
"pdf_index": 15,
"book_page": 17,
"chapter": 2,
"dimensions": {
"width": 612,
"height": 792
},
"text_spans": [
{
"text": "Rights in Real Estate",
"font": "Arial-BoldMT",
"size": 27.04,
"bold": true,
"italic": false,
"bbox": {
"x0": 72,
"y0": 150,
"x1": 400,
"y1": 177
},
"color": 0,
"sequence": 1
}
],
"analysis": {
"font_sizes": {
"27.04": 1,
"11.04": 45
},
"font_styles": {
"bold_27.04": 1,
"regular_11.04": 45
},
"likely_headings": [
{
"text": "Rights in Real Estate",
"level": 1,
"confidence": 0.95
}
],
"likely_paragraphs": [
{
"text": "Real property consists of...",
"type": "body_text"
}
]
},
"extraction_timestamp": "2025-11-08T14:30:00Z",
"extraction_tool": "rich_extractor.py v1.0"
}
要执行的Python命令
步骤1:建立页面映射
cd Calypso/tools
python3 read_page_footers.py \
--start 15 \
--end 28 \
--pdf "../PREP-AL 4th Ed 9-26-25.pdf" \
--output "../analysis/page_mapping.json"
成功指标:
- 命令以代码0退出
- 页面映射JSON已创建/更新
- 范围内的所有页面都有条目
步骤2:提取丰富数据
cd Calypso/tools
python3 rich_extractor.py \
--pdf "../PREP-AL 4th Ed 9-26-25.pdf" \
--start 15 \
--end 28 \
--output "../analysis/chapter_02/rich_extraction.json"
成功指标:
- 命令以代码0退出
- JSON文件已创建
- 文件包含text_spans数组
- 范围内的所有页面都已表示
步骤3:渲染为PNG
cd Calypso/tools
python3 -c "
import fitz
pdf = fitz.open('../PREP-AL 4th Ed 9-26-25.pdf')
for page_idx in range(15, 29):
page = pdf[page_idx]
pix = page.get_pixmap(matrix=fitz.Matrix(3, 3)) # 300%缩放以获得高分辨率
pix.save(f'../output/chapter_02/page_artifacts/page_{page_idx:02d}/02_page_{page_idx}.png')
pdf.close()
"
步骤4:提取图像(如果存在)
cd Calypso/tools
# 对于每个有图像的页面
python3 extract_images.py \
--page 17 \
--pdf "../PREP-AL 4th Ed 9-26-25.pdf" \
--output "../output" \
--mapping "../analysis/page_mapping.json"
质量检查
在声明提取完成之前:
-
文件存在性
- [ ]
01_rich_extraction.json存在 - [ ]
02_page_XX.png存在且有效 - [ ]
page_mapping.json存在
- [ ]
-
JSON有效性
- [ ] JSON文件解析无错误
- [ ] 所有必填字段都存在
- [ ] 关键字段中没有空值/未定义值
-
数据完整性
- [ ] 范围内的所有页面都有text_spans
- [ ] 文本内容不为空
- [ ] 字体大小合理(> 0)
- [ ] 边界框在页面尺寸内
-
图像质量
- [ ] PNG文件可读
- [ ] 图像尺寸与PDF页面大小匹配
- [ ] 没有损坏或空白的图像
错误处理
如果未找到PDF文件:
- 退出并显示错误消息
- 不创建部分工件
如果页面映射失败:
- 回退到默认索引(PDF索引 = 书籍页面 - 1)
- 记录警告
- 继续提取
如果丰富提取未产生文本:
- 检查页面是否为纯图像
- 在元数据中标记:
"page_type": "image_only" - 继续(ASCII预览将处理图像OCR)
如果PNG渲染失败:
- 使用回退方案:将原始PDF页面保存为PDF图像
- 记录警告
- 继续下一步
持久性与可追溯性
所有工件都包含元数据:
- 提取时间戳
- 工具版本
- 输入参数
- 处理状态
这使得:
- 可重复性(使用相同参数重新提取)
- 调试(追踪提取了哪些数据)
- 审计(跟踪工件的所有更改)
- 缓存(如果未更改则跳过重新提取)
成功标准
✓ 所有必需文件在正确的目录中创建 ✓ 丰富提取JSON有效且完整 ✓ PNG图像正确渲染 ✓ 页面映射准确 ✓ 所有数据持久化并准备好用于下一个技能 ✓ 没有提取错误或警告
后续步骤
一旦提取成功完成:
- 技能2 将从提取的数据创建ASCII预览
- 技能3 将使用提取数据 + PNG + ASCII进行HTML生成
- 所有工件可用于验证和调试
故障排除
PDF无法打开: 验证文件路径,确保PDF未损坏 未提取到文本: 页面可能是纯图像(需要OCR) 页码错误: 检查page_mapping.json的准确性 PNG图像空白: 尝试增加缩放因子(3x = 300 DPI)
实施说明
- 此技能是完全确定性的 - 相同的输入总是产生相同的输出
- Python工具确保数据质量和一致性
- 所有文件保存到持久存储以供审计跟踪
- 此阶段不涉及AI - 纯数据提取
- 准备好支持后续具有完整上下文的基于AI的HTML生成