PDFMiner提取文本丢失句号,能否适配坏/ToUnicode映射的PDF?
首先直接给你结论:默认的PDFMiner并没有内置像pdf2htmlEX或PDFium那样自动修复损坏/ToUnicode映射的能力——它的文本提取逻辑严格依赖PDF文件提供的字符映射数据,当映射损坏时,就会出现你遇到的句号缺失这类字符丢失问题。
不过你有几个可行的解决思路,根据你的需求选择:
1. 先用pdf2htmlEX转HTML再提取文本
既然你已经验证过pdf2htmlEX能正确处理这个PDF,那可以先用它把PDF转成HTML,再从HTML里提取干净的文本。这种方法简单高效,不需要修改代码逻辑。
先通过命令行工具转换:
pdf2htmlEX ESET_Okrum_and_Ketrican.pdf output.html
然后用Python的BeautifulSoup提取文本:
from bs4 import BeautifulSoup with open("output.html", "r", encoding="utf-8") as html_file: soup = BeautifulSoup(html_file, "html.parser") # 提取文本并清理多余空格 clean_text = ' '.join(soup.get_text().split()) print(clean_text)
2. 给PDFMiner添加编码兜底逻辑(进阶)
如果一定要用PDFMiner,你可以修改它的字符处理逻辑,在/ToUnicode映射失败时,尝试从标准编码表(比如WinAnsiEncoding)中匹配字符。
举个简单的修改思路:找到PDFMiner中处理字符映射的部分(比如pdfminer.pdftypes或pdfminer.converter相关模块),当获取到的字符为空时,根据字符的CID(字符ID)去对应标准编码表查找。比如句号在WinAnsiEncoding中对应0x2E,当映射失败且CID匹配这个值时,手动替换成.。
不过这种方法需要对PDFMiner的源码有一定了解,而且只针对特定问题有效,通用性不强。
3. 结合OCR作为兜底方案
如果前面的方法都不适用,你可以把PDFMiner的文本提取和OCR工具结合,当检测到提取的文本存在异常(比如超长无标点的句子)时,用OCR重新解析对应页面。
示例代码(需要安装pdf2image和pytesseract):
from pdf2image import convert_from_path import pytesseract import re def extract_text_with_ocr_fallback(pdf_path): # 先用PDFMiner提取文本(复用你原有的函数) raw_text = get_pdf_text(pdf_path) # 检测是否存在超长无句号的段落 if re.search(r'[A-Za-z]{50,}\s[A-Z]', raw_text): # 启用OCR兜底 pages = convert_from_path(pdf_path) ocr_text = '' for page in pages: ocr_text += pytesseract.image_to_string(page) + '\n' return ocr_text return raw_text if __name__ == '__main__': print(extract_text_with_ocr_fallback('./ESET_Okrum_and_Ketrican.pdf'))
补充说明:pdf2htmlEX和PDFium之所以能处理这类问题,是因为它们内置了字体替换和编码容错机制——当检测到/ToUnicode映射损坏时,会自动尝试用系统内置字体或预设编码重新解析字符,而PDFMiner的设计更偏向于严格遵循PDF规范,没有内置这类“容错”逻辑。
内容的提问来源于stack exchange,提问作者JacopoStanchi

