# 文档读取参考 根据原件实际结构编写自己的脚本,保留物理页码、原文、单位和来源。下面的库用法是示例;全页提取和实际读取是 Skill 的要求,方法和分批方式由你决定。 ## 全页提取与覆盖核对 先取得每份 PDF 的总页数,覆盖物理页 1~N,逐页提取并保存内容。一个 PDF 中可能接着装订另一台风机的报告;通过封面、报告编号、使用编号、页眉和内部页码变化识别各份报告边界,记录它们的原始物理页范围,不用文件数量推断报告数量。 有完整文本层的页面,保存并读取全文;`read_file` 返回内容被截断时继续分页读取。无文本层或主体仍是扫描图的页面,渲染后逐页 `read_file` 看图,将实际读到的文字、表格数据、单位和图注保存到逐页记录中;细节不清楚时放大或裁切回看。扫描件全文文本搜索无命中不代表其图片中没有目标风机。 覆盖清单至少区分待读、已读和无法识别;生成文本或图片时先记为待读,完成实际读取并保存识别记录后才更新为已读。可分批读取并持续保存清单,不能因读取批次数或预览长度而跳过尾页。全部页面已读、各份报告身份和页范围已核对后,再开始比较和形成结论。确实无法识别时记录具体页码与限制,返回受限结果,不把它表述为资料未提供。 ## PDF 文本与页面图片 ```python from pathlib import Path import json import pypdfium2 as pdfium source = Path('uploads/实际原件.pdf') output = Path('derived/pages') output.mkdir(parents=True, exist_ok=True) page_index = [] with pdfium.PdfDocument(source) as document: total_pages = len(document) for index in range(total_pages): page = document[index] try: text_page = page.get_textpage() try: text = text_page.get_text_range() finally: text_page.close() text_path = output / f'page-{index + 1}.txt' text_path.write_text(text, encoding='utf-8') entry = {'page': index + 1, 'text_path': str(text_path), 'text_chars': len(text), 'reading_status': 'pending'} # 这里预渲染无文本页;有水印但主体是扫描图的页面也须补充渲染。 if not text.strip(): bitmap = page.render(scale=1.5) image = bitmap.to_pil() image_path = output / f'page-{index + 1}.png' image.save(image_path) entry['image_path'] = str(image_path) image.close() bitmap.close() page_index.append(entry) finally: page.close() (output / 'index.json').write_text(json.dumps( {'source': str(source), 'total_pages': total_pages, 'pages': page_index}, ensure_ascii=False, indent=2), encoding='utf-8') ``` 这个脚本只完成预处理,所有页仍为待读。接下来必须读取各页完整文本或图片、保存识别内容并更新状态;不能直接拿生成的清单声明“已读完全文”。分析前核对已读物理页集合等于 1~total_pages,并随报告交付覆盖记录。若后来发现漏页或报告边界变化,补读并更新提取事实后再分析。 render(scale=1.5) 将 PDF 点数放大1.5倍;小字或表格可选择更大 scale。不要一次渲染许多高分辨率页面导致内存或输出超限。部分页面有水印文字但主体仍是扫描图,需要根据文本内容和原页判断,不能仅用 text.strip() 做最终路由。 通过 read_file 查看 `/workspace/derived/pages/page-N.png`。若只是某一列看不清,用 Pillow 在脚本中裁切已生成的页面,再 read_file 查看裁切图。物理页码始终引用原 PDF 的 index+1,不用截取文件的排序冒充原页。 ## 图片和裁切 ```python from PIL import Image with Image.open('derived/pages/page-3.png') as image: crop = image.crop((left, top, right, bottom)) # 坐标来自实际查看的图片 crop.save('derived/page-3-table.png') ``` 扫描原件由主 Agent 直接读取页面图,然后将实际所见事实写入自己的提取/计算脚本或 JSON。原文不清楚就放大回看,不从预计结论推数字;没有看图能力时明确说明限制。 图表可自行用字符串生成 SVG、用 Pillow 绘制,或输出 CSV。所有用于交付的图表、事实和报告都在 run_python 的 output_paths 中声明,保留成功执行凭据。