SuperAPI AI 工具集

processing-pdf

办公与效率

查看项目

更新于 10-16 07:45

技能介绍

PDF Processing 是一套面向 PDF 文件处理的技能,使用命令行工具与 Python 库完成 PDF 数据的提取、扫描件读取与文件操作。对于扫描版 PDF,可将页面转换为图片,再由大语言模型利用其内置图像理解能力读取内容。

【前置条件】 在运行任何 Python 脚本之前,需先激活 opencode 虚拟环境:

source ~/.local/opencode-venv/bin/activate

之后正常使用 python3 scripts/... 即可。

【可用工具】

  • pdf-extractor 智能体:全局智能体(通过 task 调度),用于完整 PDF 提取(所有页面、所有数据、结构化文件夹树)。
  • pdftotext:系统工具(Poppler),用于快速文本提取。
  • pdfinfo:系统工具(Poppler),用于读取元数据、页数。
  • pypdf:Python(虚拟环境),用于合并、拆分、旋转。
  • pdfplumber:Python(虚拟环境),用于表格提取、详细文本。
  • to_images.py:Python 脚本(虚拟环境),用于将页面转换为 PNG 图片。

【决策指南】 需要处理 PDF 时,可按以下路径选择:

  • 需要提取 PDF 中的全部内容:调度 pdf-extractor 智能体。它会把所有页面转换为图片、逐页读取,并将每页结果保存到 extracted_data/<pdf_name>/page_NNN/content.md,同时保存图片与摘要。
  • 需要从普通 PDF 快速提取文本:简单场景用 pdftotext input.pdf output.txt;需要页码时用 python3 scripts/extract_text.py input.pdf。
  • 需要提取表格:python3 scripts/extract_tables.py input.pdf -o ./tables/。
  • 需要填写表单:先用 python3 scripts/check_forms.py input.pdf 检查字段,再用 python3 scripts/fill_form.py input.pdf fields.json output.pdf 填写。
  • 需要快速读取扫描版 PDF:先用 python3 scripts/to_images.py scanned.pdf -o ./pages/ --dpi 200 转换,再读取图片并提取所需内容。
  • 需要合并/拆分/旋转:参见下方 pypdf 示例。
  • 大文件(>50MB):快速文本用 pdftotext(最快);按页范围用 pdftotext -f N -l M input.pdf。

【完整 PDF 提取】 若需完整提取 PDF 中的所有数据(文本、表格、表单、结构),可调度 pdf-extractor 智能体。它会:将所有页面转换为 PNG 图片;使用 LLM 视觉逐张读取图片;提取文本、表格、关键事实、表单字段与备注;按页输出到 extracted_data/<pdf_name>/page_NNN/,其中 page_NNN.png 为页面图片,content.md 为以 markdown 记录的全部文本与提取事实,并按需生成其他 LLM 可读文件;创建 summary.md 作为文档级概览。

适用场景:需要全部数据的多页文档;扫描版或扫描与数字混合的 PDF;布局复杂(表格、分栏、表单)的文档;需要结构化、可浏览的结果文件夹树时。

【快速提取(不使用智能体)】 单页或快速查看时,可使用以下手动步骤。

读取扫描版 PDF(快速、不使用智能体): 当 PDF 为扫描件(无可选文本)时,将其页面转换为图片并让 LLM 读取。 步骤 1:检测是否为扫描版:pdftotext document.pdf - | head -20。若输出为空或仅空白,则为扫描版。 步骤 2:转换页面为图片:

所有页面 200 DPI(对大多数文档足够)

python3 scripts/to_images.py document.pdf -o ./pdf-pages/ --dpi 200

手写或低质量扫描件使用更高画质

python3 scripts/to_images.py document.pdf -o ./pdf-pages/ --dpi 300 步骤 3:读取图片:直接引用生成的 PNG 文件,LLM 可原生读取。可要求其提取文本、表格、字段或回答关于文档内容的问题。 步骤 4:清理:rm -rf ./pdf-pages/

扫描版 PDF 提示:200 DPI 适用于大多数文档;300 DPI 用于手写内容或模糊扫描件;大 PDF 可分批转换页面(先用 pypdf 拆分再转换);读取后始终清理生成的图片目录。

【文本提取】 快速提取(pdftotext):

简单提取

pdftotext input.pdf output.txt

单页

pdftotext -f 3 -l 3 input.pdf page3.txt

保留布局

pdftotext -layout input.pdf output.txt

页面范围

pdftotext -f 5 -l 10 input.pdf pages_5_10.txt

带页码(脚本):python3 scripts/extract_text.py input.pdf 获取 PDF 信息:pdfinfo input.pdf

【表格提取】 脚本(推荐):python3 scripts/extract_tables.py input.pdf -o ./tables/ Python(内联): import pdfplumber import csv

with pdfplumber.open("input.pdf") as pdf: for i, page in enumerate(pdf.pages): tables = page.extract_tables() for j, table in enumerate(tables): with open(f"page{i+1}_table{j+1}.csv", "w", newline="") as f: writer = csv.writer(f) for row in table: writer.writerow([cell or "" for cell in row])

【表单处理】 检查可填写字段:python3 scripts/check_forms.py input.pdf 填写表单:python3 scripts/fill_form.py input.pdf fields.json output.pdf 其中 fields.json 内容示例: { "field_name": "John Smith", "email": "john@example.com", "date": "2026-05-04" }

【PDF 操作(pypdf)】 合并 PDF: from pypdf import PdfReader, PdfWriter

writer = PdfWriter() for pdf_file in ["file1.pdf", "file2.pdf", "file3.pdf"]: reader = PdfReader(pdf_file) for page in reader.pages: writer.add_page(page)

with open("merged.pdf", "wb") as f: writer.write(f)

拆分为单页: from pypdf import PdfReader, PdfWriter

reader = PdfReader("input.pdf") for i, page in enumerate(reader.pages): writer = PdfWriter() writer.add_page(page) with open(f"page_{i+1:03d}.pdf", "wb") as f: writer.write(f)

旋转页面: from pypdf import PdfReader, PdfWriter

reader = PdfReader("input.pdf") writer = PdfWriter() for page in reader.pages: page.rotate(90) # 90, 180, or 270 degrees writer.add_page(page)

with open("rotated.pdf", "wb") as f: writer.write(f)

删除页面: from pypdf import PdfReader, PdfWriter

reader = PdfReader("input.pdf") writer = PdfWriter() pages_to_keep = {0, 1, 4, 5} # 0-indexed for i, page in enumerate(reader.pages): if i in pages_to_keep: writer.add_page(page)

with open("trimmed.pdf", "wb") as f: writer.write(f)

元数据:python3 scripts/metadata.py input.pdf 转换为图片:python3 scripts/to_images.py input.pdf --dpi 200

【大文件】 对于大 PDF(>50MB):使用 pdftotext 快速提取(比 Python 更快);用 pdfplumber 分批处理页面;使用 pdftotext 的 -f 和 -l 参数指定页面范围。

写入大输出文件:若从超大 PDF 提取文本,应增量写入输出(每次编辑约 1000 tokens),而非一次性完成。

【常见模式】 在 PDF 中搜索文本:pdftotext input.pdf - | grep -n "search term" 比较两个 PDF(文本差异): pdftotext doc1.pdf - > /tmp/doc1.txt pdftotext doc2.pdf - > /tmp/doc2.txt diff /tmp/doc1.txt /tmp/doc2.txt

【边界情况】 加密 PDF: from pypdf import PdfReader

reader = PdfReader("encrypted.pdf") if reader.is_encrypted: reader.decrypt("") # Try empty password first

损坏或无效 PDF: try: with pdfplumber.open("file.pdf") as pdf: # process... except Exception as e: print(f"Error processing PDF: {e}")

超大 PDF(>100MB):使用 pdftotext 以提升速度;用 pdfplumber 按页分批处理;避免将整个文件加载到内存。

混合内容(部分页面为扫描件、部分不是):先尝试标准提取(pdftotext);检查哪些页面返回空文本;仅将这些页面转换为图片并让 LLM 读取。