| name | pdf-parsing |
| description | 当需要用 structai.read_pdf 将 PDF 文档解析成本地 Markdown、抽取图片资源,并处理 MinerU 解析缓存或代理重试问题时使用。 |
PDF 解析
目标
把 PDF 文档解析成本地可读取、可搜索、可复制的 Markdown,并抽取 PDF 中的图片资源。解析完成后,后续阅读应优先使用本地 Markdown 文件;重复调用 structai.read_pdf 也会优先复用本地解析结果,不会在本地结果已存在时重复上传同一个 PDF。
依赖安装
当前 skill 对照的关键解析依赖:
structai package version:0.1.24。
structai GitHub HEAD:d20df602578bee124a9c93b293493e63212d0aab。
- 更新本 skill 前,先确认
structai.read_pdf 行为是否变化;如果上游版本或 HEAD 变化,必须重新阅读 read_pdf 源码和 structai_skill() 输出。
pip install structai
如果包索引中找不到 structai,或需要使用 GitHub 仓库中的最新代码:
pip install "git+https://github.com/black-yt/structai.git"
校验:
python3 -c "from structai import read_pdf; import inspect; print(inspect.signature(read_pdf))"
如果当前环境同时有多个 Python,请确认 pip 和 python3 指向同一个环境:
python3 -m pip show structai
python3 -c "import structai; print(structai.__file__)"
read_pdf 源码追溯
read_pdf 行为以当前安装版本源码为准;如果缓存、上传、下载、图片路径或返回值和预期不一致,先读源码再判断。
inspect.signature(read_pdf) 用于看函数参数。
inspect.getsource(read_pdf) 用于看 read_pdf 入口逻辑。
structai.__file__ 和 structai.pdf.__file__ 用于定位安装包源码文件。
- 源码只用于阅读和定位问题,不要改源码,不要直接修改
site-packages 或共享环境;需要改库时,先 clone https://github.com/black-yt/structai,在用户确认后用 editable install。
python3 - <<'PY'
import inspect
import structai
import structai.pdf as pdf_mod
from structai import read_pdf
print("structai:", structai.__file__)
print("structai.pdf:", pdf_mod.__file__)
print("signature:", inspect.signature(read_pdf))
print(inspect.getsource(read_pdf))
PY
如果要继续追 read_pdf 调用的内部函数,先查看 structai.pdf 模块源码路径,再按函数名读取:
python3 - <<'PY'
import inspect
import structai.pdf as pdf_mod
print(pdf_mod.__file__)
for name in ["get_headers"]:
obj = getattr(pdf_mod, name, None)
if obj is not None:
print(f"\n===== {name} =====")
print(inspect.getsource(obj))
PY
MinerU Token
structai.read_pdf 会调用 MinerU 精准解析 API。该 API 需要 Token,且请求头格式为 Authorization: Bearer <Token>。
获取方式:
- 打开 https://mineru.net/。
- 注册或登录账号。
- 进入 API / Token 管理页面,免费申请 API Token。
- 把 Token 设置为环境变量
MINERU_TOKEN。
Linux / macOS / WSL:
export MINERU_TOKEN="your_mineru_token"
Windows PowerShell:
$env:MINERU_TOKEN = "your_mineru_token"
验证环境变量是否已设置:
python3 -c "import os; print('MINERU_TOKEN set:', bool(os.environ.get('MINERU_TOKEN')))"
验证 structai 能读到 Token:
python3 -c "from structai.pdf import get_headers; h=get_headers(); print(h['Authorization'][:16] + '...')"
不要把真实 Token 写进代码、文档、Git 仓库或聊天记录。需要长期生效时,把 export MINERU_TOKEN=... 放到自己的 shell 配置文件或系统环境变量中。
如果未设置 Token,structai.read_pdf 会报类似错误:
MINERU_TOKEN not found. Please register a free account at https://mineru.net/ and set the environment variable.
为了避免解析时生成 __pycache__,建议运行命令时加上:
PYTHONDONTWRITEBYTECODE=1
基本解析
当前 structai.read_pdf 封装使用 MinerU 批量本地文件上传接口 /api/v4/file-urls/batch,适合解析本地 PDF 文件。MinerU 官方文档说明:精准解析 API 需要 Token,支持表格和公式识别,单个文件大小上限为 200 MB,页数上限为 200 页;批量上传接口单次申请上传链接不能超过 50 个文件。
如果 PDF 超过接口限制,先按页拆分或压缩,再分别解析。
Python 调用:
from structai import read_pdf
result = read_pdf("paper.pdf")
命令行解析:
env PYTHONDONTWRITEBYTECODE=1 python3 -c "from structai import read_pdf; read_pdf('paper.pdf')"
带摘要输出:
env PYTHONDONTWRITEBYTECODE=1 python3 -c "from structai import read_pdf
p='paper.pdf'
r=read_pdf(p)
print('success', bool(r))
if r:
print('path', r['path'])
print('text_length', len(r['text']))
print('image_count', len(r['img_paths']))
print(r['text'][:1200])"
本地解析结果
对 paper.pdf 调用 read_pdf 后,通常会在 PDF 同级位置生成同名目录:
paper/
full.md
layout.json
*_content_list.json
图片资源子目录
常用文件:
full.md:解析后的全文 Markdown。
layout.json:版面结构信息,可用于排查版面解析问题。
*_content_list.json:内容块列表,可辅助定位段落、标题、表格和图片。
- 图片资源子目录:保存从 PDF 中抽取出来的图片或版面切片。
如果同名目录下已经存在 full.md,read_pdf 会优先复用本地解析结果,并直接读取本地 Markdown 和图片路径;这种情况下重复调用不会再次把同一个 PDF 上传到 MinerU。因此不用担心为了获取返回值而重复调用 read_pdf("paper.pdf") 会产生重复上传。只有删除本地解析目录、缺失 full.md、更换 PDF 路径或替换原始 PDF 后,才需要重新上传解析。
实际阅读时仍建议直接打开 full.md,这样最快,也方便手工检查解析质量。
返回值结构
成功时通常返回:
{
"path": "paper.pdf",
"text": "...",
"img_paths": [...],
"imgs": [...]
}
字段含义:
path:原始 PDF 路径。
text:full.md 的全文内容。
img_paths:Markdown 正文实际引用到的图片路径。
imgs:对应的 PIL 图片对象。
读取与检查
读取开头:
sed -n '1,120p' paper/full.md
查看标题结构:
rg -n "^#|^##|^###" paper/full.md
查看图片引用:
rg -n "!\\[" paper/full.md
至少确认:
full.md 存在且非空。
- 标题、摘要、章节标题基本可读。
- 图表引用能对应到本地图片资源。
- 关键表格没有严重错行。
- 公式和特殊符号没有影响理解。
常见问题
-
MINERU_TOKEN not found:先到 https://mineru.net/ 申请 Token,再设置 MINERU_TOKEN 环境变量。
-
401、403 或 Authorization 相关错误:检查 Token 是否复制完整、是否过期、当前 shell 是否能读取 MINERU_TOKEN。
-
解析返回 None:确认 Token 已设置;关闭代理重试;检查是否已有可读 full.md;如果仍失败,记录错误信息。
-
Markdown 局部乱码或断词:用 full.md 快速定位章节,对关键段落、公式和表格回到 PDF 原文或抽取图片核对。
-
图片目录文件很多:优先看 Markdown 中实际引用的图片,再按后续任务需要浏览其他图片。
-
网络问题与代理处理:MinerU 处理和结果下载需要网络。如果遇到 SSLError、UNEXPECTED_EOF_WHILE_READING、Max retries exceeded、Connection reset、上传成功但结果压缩包下载失败等问题,优先关闭代理后重试。关闭代理时仍要保留 MINERU_TOKEN:
env -u HTTP_PROXY -u HTTPS_PROXY -u ALL_PROXY -u http_proxy -u https_proxy -u all_proxy -u NO_PROXY -u no_proxy MINERU_TOKEN="$MINERU_TOKEN" PYTHONDONTWRITEBYTECODE=1 python3 -c "from structai import read_pdf; read_pdf('paper.pdf')"
处理顺序:
- 保留当前目录,不要删除已经生成的解析缓存。
- 确认
MINERU_TOKEN 已设置。
- 用关闭代理的命令重试同一个 PDF。
- 如果重试成功,后续直接读取本地
full.md。
- 如果重试失败但已有可读
full.md,直接使用本地 Markdown。
- 如果没有
full.md,记录完整错误信息,稍后重试或更换网络环境。