Python爬取PDF遇‘EOF marker not found’错误,文件已含%%EOF
PDF爬取中「EOF marker not found」问题的解决方案
问题背景
用Python爬取PDF时,1.6%的文件会触发PyPDF2抛出的「EOF marker not found」错误,但检查文件字节内容后,发现末尾确实存在%%EOF标记,且标记后紧跟换行符,距离文件末尾不足1024字节。当前使用流程:requests.get获取文件 → ByteIO加载内存PDF → PyPDF2读取。试过网上的旧修复函数(已失效),也尝试过手动追加EOF标记,均未解决问题。
排查与分析
针对示例PDF,可能的问题点包括:
- 请求内容不完整:
requests.get默认可能未完整接收响应体,导致内存中的PDF字节流存在隐性截断或损坏; - PyPDF2解析严格性:PyPDF2对PDF格式校验苛刻,若
%%EOF标记前后存在特殊空白字符、不可见字符,或标记格式不符合其预期(比如未单独占一行),会判定为EOF缺失; - 传输过程字节篡改:部分服务器返回的PDF在传输中出现字节异常,导致解析失败。
可行解决方法
1. 确保请求完整接收PDF内容
使用stream模式请求,校验响应内容长度与实际接收字节数是否一致,避免截断:
import requests from io import BytesIO def get_complete_pdf(url): response = requests.get(url, stream=True) response.raise_for_status() # 校验内容长度(若服务器返回) content_length = response.headers.get('Content-Length') if content_length: content_length = int(content_length) content = b''.join(response.iter_content(chunk_size=1024)) if len(content) != content_length: # 可重试请求或标记文件为损坏 return None else: content = response.content return BytesIO(content)
2. 手动修复PDF的EOF标记
定位到最后一个%%EOF标记,截断其后的多余内容,确保PyPDF2能识别:
def fix_pdf_eof(pdf_stream): pdf_stream.seek(0) pdf_bytes = pdf_stream.read() eof_marker = b'%%EOF' eof_pos = pdf_bytes.rfind(eof_marker) if eof_pos == -1: return pdf_stream # 无EOF标记,返回原流 # 保留EOF标记及之后的合法换行,截断多余内容 end_pos = eof_pos + len(eof_marker) while end_pos < len(pdf_bytes) and pdf_bytes[end_pos] in (b'\n', b'\r', b' '): end_pos += 1 fixed_bytes = pdf_bytes[:end_pos] return BytesIO(fixed_bytes)
3. 替换为兼容性更好的PDF库
PyPDF2对不规范PDF的兼容性较差,可改用PyMuPDF(fitz),它对格式瑕疵的容忍度更高:
import fitz # 配合上面的get_complete_pdf函数使用 pdf_stream = get_complete_pdf("https://www.burlingtonvt.gov/sites/default/files/08.27.2022.pdf") if pdf_stream: doc = fitz.open("pdf", pdf_stream.read()) # 执行后续解析操作(比如提取文本) text = doc.get_text() doc.close()
内容的提问来源于stack exchange,提问作者zionc
相关产品推荐
相关产品推荐

