使用pypdf读取特定PDF时遇AttributeError错误,求解决方法
问题
使用pypdf库提取PDF页面时,多数文件可正常处理,但某特定文件触发以下异常:
File "/home/obr01/python-venv/opencapture/lib/python3.10/site-packages/pypdf/_page.py", line 2342, in __getitem__ len_self = len(self) File "/home/obr01/python-venv/opencapture/lib/python3.10/site-packages/pypdf/_page.py", line 2333, in __len__ return self.length_function() File "/home/obr01/python-venv/opencapture/lib/python3.10/site-packages/pypdf/_reader.py", line 452, in _get_num_pages self._flatten() File "/home/obr01/python-venv/opencapture/lib/python3.10/site-packages/pypdf/_reader.py", line 1185, in _flatten pages = catalog["/Pages"].get_object() # type: ignore AttributeError: 'NoneType' object has no attribute 'get_object'
排查发现该文件的Reader trailer中/Pages字段值为None,执行以下代码:
pdf_reader = pypdf.PdfReader(file_path, strict=False) print(pdf_reader.trailer['/Root']['/Pages'])
输出结果:
Object 2178 0 not defined. None
求处理该异常的方法。
解决方案
1. 提前校验PDF结构有效性
在尝试获取页面前,先检查/Pages字段是否存在且有效,从源头避免异常:
from pypdf import PdfReader pdf_reader = PdfReader(file_path, strict=False) root_catalog = pdf_reader.trailer.get('/Root') # 确认Root目录和Pages字段均有效 if root_catalog and root_catalog.get('/Pages') is not None: # 正常执行页面提取逻辑 for page in pdf_reader.pages: extracted_text = page.extract_text() # 后续处理操作 else: print(f"文件 {file_path} 结构异常:/Pages字段无效或缺失")
2. 捕获特定异常做降级处理
直接针对触发的AttributeError捕获,区分是结构异常导致的问题后,执行跳过或标记逻辑:
from pypdf import PdfReader import traceback try: pdf_reader = PdfReader(file_path, strict=False) # 尝试访问页面触发可能的异常 pages = pdf_reader.pages # 页面处理逻辑 except AttributeError as e: if "'NoneType' object has no attribute 'get_object'" in str(e): print(f"跳过文件 {file_path}:PDF结构损坏,无法识别页面信息") # 可添加日志记录、文件标记等操作 else: # 处理其他非结构问题导致的AttributeError traceback.print_exc()
3. 尝试修复损坏的PDF结构
这类问题多由PDF文件本身损坏或不规范导致,可尝试用pypdf自带的读写功能修复后再处理:
from pypdf import PdfReader, PdfWriter try: # 读取损坏的PDF文件 broken_reader = PdfReader(file_path, strict=False) writer = PdfWriter() # 尝试添加所有可识别的页面 for page in broken_reader.pages: writer.add_page(page) # 保存修复后的文件 fixed_file_path = f"fixed_{file_path}" with open(fixed_file_path, "wb") as f: writer.write(f) # 重新读取修复后的文件进行处理 fixed_reader = PdfReader(fixed_file_path) # 后续页面提取逻辑 except Exception as e: print(f"修复文件 {file_path} 失败:{str(e)}")
注意:如果PDF损坏程度过高,修复可能无法成功,此时只能跳过该文件。
内容的提问来源于stack exchange,提问作者Oussama BRICH
相关产品推荐
相关产品推荐

