You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 18:23:21