Python库实现PDF转TXT时文本提取不全/出错,求解决方案
PDF转TXT提取不全/错误的解决方案
针对你遇到的问题,结合PDF的两种常见类型(原生可编辑PDF、扫描件PDF),给出以下针对性技术方案:
一、针对原生可编辑PDF:用pdfplumber优化提取逻辑
原生PDF出现提取错误,大多是因为文本分层、内嵌字体或布局复杂导致基础库解析失效,pdfplumber对复杂布局的支持远优于pdfminer/pdftotext:
import pdfplumber def convert_pdf_to_txt(path): full_text = "" with pdfplumber.open(path) as pdf: for page in pdf.pages: # 启用布局分析,保留文本排版结构,避免错乱 page_text = page.extract_text(layout=True) if page_text: full_text += page_text + "\n\n" return full_text # 调用示例 pdf_path = '/content/drive/MyDrive/PDF/file.pdf' extracted_text = convert_pdf_to_txt(pdf_path) # 保存时指定UTF-8编码,避免乱码 with open('extracted_text.txt', 'w', encoding='utf-8') as file: file.write(extracted_text) print('文本已保存到"extracted_text.txt"文件。')
如果仍有缺失,可尝试逐个提取单词再拼接:
# 替换extract_text部分 words = page.extract_words() page_text = " ".join([word['text'] for word in words])
二、针对扫描件(图片型PDF):升级OCR模型
如果你的PDF是扫描件,pytesseract默认模型精度远低于专业在线工具,可换用以下方案:
选项1:用EasyOCR(免费、多语言、高精度)
EasyOCR的预训练模型比Tesseract默认版本更精准,无需额外训练:
import easyocr from pdf2image import convert_from_path import os def convert_scanned_pdf_to_txt(path): # 高DPI转换PDF为图片,提升识别精度 pages = convert_from_path(path, dpi=300) # 根据PDF语言调整,比如['zh-cn', 'en']支持中英混合 reader = easyocr.Reader(['en']) full_text = "" for idx, page in enumerate(pages): temp_img = f"temp_page_{idx}.jpg" page.save(temp_img, 'JPEG') # 识别文本,detail=0只返回纯文本 result = reader.readtext(temp_img, detail=0) full_text += "\n".join(result) + "\n\n" os.remove(temp_img) return full_text # 调用示例同原生PDF
选项2:调用云OCR API(效果与在线工具一致)
如果在线工具用的是云服务(如Google Cloud Vision、AWS Textract),直接调用对应API可获得相同效果,以Google Cloud Vision为例:
from google.cloud import vision from pdf2image import convert_from_path import io def convert_with_cloud_vision(path): client = vision.ImageAnnotatorClient() pages = convert_from_path(path, dpi=300) full_text = "" for page in pages: img_byte_arr = io.BytesIO() page.save(img_byte_arr, format='JPEG') image = vision.Image(content=img_byte_arr.getvalue()) # 文档级OCR,保留排版 response = client.document_text_detection(image=image) full_text += response.full_text_annotation.text + "\n\n" return full_text
(需提前配置Google Cloud服务账号,适合高精度需求场景)
三、处理特殊情况
1. 加密PDF
先解密再提取:
from PyPDF2 import PdfReader, PdfWriter def decrypt_pdf(input_path, output_path): reader = PdfReader(input_path) if reader.is_encrypted: # 无密码加密传空字符串,有密码则传入对应密码 reader.decrypt("") writer = PdfWriter() for page in reader.pages: writer.add_page(page) with open(output_path, 'wb') as f: writer.write(f) return output_path # 先解密再调用提取函数 decrypted_pdf = decrypt_pdf(pdf_path, 'decrypted_file.pdf') extracted_text = convert_pdf_to_txt(decrypted_pdf)
2. 内嵌字体乱码
用pdftotext的-layout参数强制保留布局:
import subprocess def convert_with_pdftotext(path): # 调用系统pdftotext命令,-layout参数保留原始排版 subprocess.run(["pdftotext", "-layout", path, "extracted_text.txt"], check=True)
验证步骤
- 先判断PDF类型:用阅读器尝试选中文本,能选中则为原生PDF,不能则为扫描件;
- 对应选择上述方案,优先用pdfplumber处理原生PDF,EasyOCR处理扫描件;
- 若仍有问题,用
pdfplumber的page.objects查看PDF内所有文本对象,排查是否存在隐藏文本或分层文本。
内容的提问来源于stack exchange,提问作者Olivalej
相关产品推荐
相关产品推荐

