pdfplumber 可靠提取含表格、多栏、混排文本的 pdf,但不支持 ocr 和解密,对扫描件、加密 pdf 或结构损坏文件会失败;常见报错源于密码保护、acrobat 优化或伪 pdf,需用 qpdf 解密、file 命令验证格式、strict=false 绕过语法错误,扫描件须先 ocr;extract_table() 返回 none 因缺乏线条或对齐文本,应改用 extract_tables()、crop 指定区域或调整 table_settings;中文乱码主因字体未嵌入或编码异常,可检查查看器复制效果、启用 all_texts、分析 page.chars 字体名;调试首选 page.to_image().save() 直观判断 pdf 类型。

PDFPlumber 能可靠提取带表格、多栏、混排文本的 PDF,但对扫描件、加密 PDF 或严重错位的页面会直接失败——它不 OCR,也不解密。
为什么 pdfplumber.open() 会报 PDFSyntaxError 或卡住
常见于:PDF 文件被密码保护、用 Adobe Acrobat “优化” 过(移除了结构元数据)、或由某些打印机驱动生成的“伪 PDF”。pdfplumber 依赖底层 pdfminer.six 解析原始流,不处理加密层或图像层。
- 先用
qpdf --decrypt input.pdf output.pdf尝试解密(仅限用户密码,非所有情况有效) - 用
file input.pdf检查是否真为 PDF(有时扩展名是 .pdf,实际是 .jpg 重命名) - 加
strict=False参数绕过部分语法错误:pdfplumber.open("x.pdf", strict=False) - 若页面内容为空但无报错,大概率是扫描件——必须先 OCR(如用
pytesseract+PIL提取图像再识别)
提取表格时 page.extract_table() 返回 None 怎么办
PDFPlumber 的表格检测基于文本坐标和线条(lines)的几何聚类,不是语义理解。返回 None 表示它没找到足够支撑“表格结构”的线或对齐文本块。
- 优先用
page.extract_tables()(复数),它尝试多种策略,比单表更鲁棒 - 手动指定区域:
page.crop((x0, top, x1, bottom)).extract_table()缩小搜索范围 - 传入
table_settings调整灵敏度,例如放宽竖线容忍:{"vertical_strategy": "text", "horizontal_strategy": "lines"} - 检查 PDF 是否真的有可见表格线——很多“表格”只是靠空格/制表符对齐,此时应改用
page.extract_text(x_tolerance=1, y_tolerance=3)配合正则解析
中文乱码、字体缺失导致文字提取为空或方块
PDFPlumber 默认只提取已嵌入字体中能映射到 Unicode 的字符。中文字体常未完全嵌入,或用自定义编码(如 GBK 编码的 CID 字体),pdfminer 无法自动还原。
- 确认 PDF 中文字是否可被系统 PDF 查看器正常复制——如果查看器也复制出乱码,说明源文件本身字体信息损坏
- 强制启用字符映射回退:
pdfplumber.open("x.pdf", password="", laparams={"all_texts": True}) - 对特定页面,用
page.chars获取原始字形位置和编码值,结合字体名(c["fontname"])人工排查是否为常见中文字体(如SimSun,NotoSansCJKsc) - 避免依赖
page.extract_text()的默认输出;改用[c["text"] for c in page.chars if c["text"].strip()]拿原始字符流再清洗
真正麻烦的永远不是“怎么调用函数”,而是判断当前 PDF 属于哪一类坏样本:是缺字体、缺线、缺文本、还是根本没文本。多开一个 page.to_image().save("debug.png") 看一眼,比调十次参数更快。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











