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

如何用Python提取PDF中非标准表单的复选框与单选框选中状态?

提取非标准PDF复选框/单选框状态的Python方案

你的情况确实是这些复选框属于渲染后的图形元素,而非PDF标准交互式表单字段,所以表单字段相关API无法读取。以下是两种可行的Python解决方案:

方案一:用PyMuPDF(fitz)分析页面图形元素

PyMuPDF可以提取页面中的所有图形路径,通过判断复选框的形状(矩形)是否被填充,或者是否存在打勾的路径,来识别选中状态。

示例代码:

import fitz  # PyMuPDF

def check_checkbox_status(pdf_path, page_num=-1):
    doc = fitz.open(pdf_path)
    page = doc[page_num]  # 取最后一页,和原代码逻辑一致
    
    # 获取页面所有图形元素
    drawings = page.get_drawings()
    checkbox_states = []
    
    # 遍历图形,筛选复选框相关元素
    for drawing in drawings:
        # 复选框通常是矩形,先筛选矩形路径
        if drawing["type"] == "rect":
            rect = drawing["rect"]
            # 检查是否有填充(选中的复选框可能是填充的矩形)
            has_fill = drawing["fill"] is not None and drawing["fill"] != (1,1,1)  # 排除白色填充
            
            # 或者检查是否存在打勾的路径(有些是空心框加勾)
            has_checkmark = False
            for path in drawing["items"]:
                if path[0] == "c":  # 贝塞尔曲线,打勾常用这种路径
                    has_checkmark = True
                    break
            
            if has_fill or has_checkmark:
                # 获取该复选框附近的文本,关联对应选项
                nearby_text = page.get_text("text", clip=rect + fitz.Rect(0,0,50,0))  # 向右扩展区域取文本
                checkbox_states.append((nearby_text.strip(), "选中"))
            else:
                nearby_text = page.get_text("text", clip=rect + fitz.Rect(0,0,50,0))
                checkbox_states.append((nearby_text.strip(), "未选中"))
    
    doc.close()
    return checkbox_states

# 调用示例
states = check_checkbox_status("data/test.pdf")
for item in states:
    print(f"选项:{item[0]},状态:{item[1]}")

说明:

  • 不同工具生成的复选框图形逻辑可能不同,需要根据实际PDF调整判断条件(比如填充色、路径形状)
  • get_drawings()能获取所有矢量图形,比纯文本提取更精准捕捉图形状态

方案二:结合OCR识别(适合复杂图形场景)

如果图形规则不统一,可将PDF页面转为图片,用OCR工具识别选中标记(比如√、X),再关联对应文本。

示例代码(依赖PyMuPDF和pytesseract):

import fitz
import pytesseract
from PIL import Image

def ocr_checkbox_status(pdf_path, page_num=-1):
    doc = fitz.open(pdf_path)
    page = doc[page_num]
    
    # 将页面转为图片
    pix = page.get_pixmap(dpi=300)  # 高DPI提升识别精度
    img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
    
    # OCR识别所有文本和位置
    ocr_data = pytesseract.image_to_data(img, output_type=pytesseract.Output.DICT)
    
    checkbox_states = []
    # 遍历OCR结果,查找包含选中标记的区域
    for i in range(len(ocr_data["text"])):
        text = ocr_data["text"][i].strip()
        if text in ["√", "X", "✓", "×"]:  # 常见选中标记
            # 获取标记右侧的文本(对应选项)
            x, y = ocr_data["left"][i], ocr_data["top"][i]
            # 查找同一行附近的文本
            for j in range(len(ocr_data["text"])):
                if abs(ocr_data["top"][j] - y) < 10 and ocr_data["left"][j] > x:
                    option_text = ocr_data["text"][j].strip()
                    checkbox_states.append((option_text, "选中"))
                    break
        elif text in ["Yes", "No", "Check-1", "Check-2", "Check-3"]:  # 你的选项文本
            # 检查该文本左侧是否有选中标记
            x, y = ocr_data["left"][i], ocr_data["top"][i]
            has_mark = False
            for j in range(len(ocr_data["text"])):
                if abs(ocr_data["top"][j] - y) < 10 and ocr_data["left"][j] < x - 10:
                    mark = ocr_data["text"][j].strip()
                    if mark in ["√", "X", "✓", "×"]:
                        has_mark = True
                        break
            status = "选中" if has_mark else "未选中"
            checkbox_states.append((text, status))
    
    doc.close()
    return checkbox_states

# 调用示例
states = ocr_checkbox_status("data/test.pdf")
for item in states:
    print(f"选项:{item[0]},状态:{item[1]}")

说明:

  • 需要先安装Tesseract OCR引擎,并配置好环境变量
  • 可根据实际选中标记调整匹配的字符集合,提升识别准确率

内容的提问来源于stack exchange,提问作者Prahlad Yeri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:24:52