如何通过Python或OCR技术提取PDF中选中的单选按钮选项?
提取PDF中选中单选按钮响应的可行方法
针对你遇到的问题,以下是几种实用的Python方案,覆盖原生可编辑PDF和扫描版PDF场景:
1. 原生PDF:结合pdfplumber的图形检测+文本匹配
如果是原生可编辑PDF,pdfplumber可以检测页面中的图形元素(比如选中单选按钮的填充圆点),再匹配附近的文本:
import pdfplumber def extract_selected_radio_buttons(pdf_path): selected_options = [] with pdfplumber.open(pdf_path) as pdf: for page in pdf.pages: # 筛选填充的圆形(选中的单选按钮,需根据实际尺寸调整宽高阈值) circles = [obj for obj in page.objects['rects'] if abs(obj['width'] - obj['height']) < 2 and obj['fill'] is not None] for circle in circles: # 扩大按钮区域范围,提取对应文本 text_area = page.within_bbox((0, circle['top']-5, page.width, circle['bottom']+5)) option_text = text_area.extract_text().strip() if option_text: selected_options.append(option_text) return selected_options # 调用示例 print(extract_selected_radio_buttons("your_form.pdf"))
注意:需要根据PDF中单选按钮的实际大小,调整圆形筛选的宽高差值、填充值等参数。
2. 原生PDF:PyMuPDF(fitz)图形+文本定位
PyMuPDF对PDF的图形和文本定位精度更高,适合处理表单类文档:
import fitz def extract_selected_with_pymupdf(pdf_path): selected = [] doc = fitz.open(pdf_path) for page in doc: # 获取页面所有绘图对象,筛选非白色填充的圆形(选中状态) drawings = page.get_drawings() for draw in drawings: if draw['fill'] != (1,1,1) and draw['type'] == 'circle': # 扩大图形区域,匹配对应文本块 rect = fitz.Rect(draw['rect']) expand_rect = rect + (-5, -5, 5, 5) text_blocks = page.get_text("blocks", clip=expand_rect) for block in text_blocks: text = block[4].strip() if text and text not in selected: selected.append(text) doc.close() return selected # 调用示例 print(extract_selected_with_pymupdf("your_form.pdf"))
3. 扫描版PDF:OCR+图像处理
如果是扫描生成的非可编辑PDF,需要结合OpenCV预处理图像,再用OCR提取文本:
import cv2 import pytesseract import numpy as np from pdf2image import convert_from_path def extract_scanned_selected(pdf_path): selected = [] # 将PDF转换为图片 pages = convert_from_path(pdf_path) for page_img in pages: img = cv2.cvtColor(np.array(page_img), cv2.COLOR_RGB2BGR) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 阈值分割,突出选中的圆点 _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV) # 检测圆形轮廓 contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: area = cv2.contourArea(cnt) # 筛选符合单选按钮大小的轮廓 if 50 < area < 200: x, y, w, h = cv2.boundingRect(cnt) # 提取按钮右侧的文本区域 text_region = img[y-5:y+h+5, x+w+5:x+w+300] text = pytesseract.image_to_string(text_region, lang='eng').strip() if text: selected.append(text) return selected # 调用示例 print(extract_scanned_selected("scanned_form.pdf"))
注意:需提前安装pdf2image、opencv-python,并配置好Tesseract OCR的路径。
4. AcroForm标准表单:直接提取字段值
如果PDF是标准的AcroForm表单,无需检测图形,直接提取单选按钮的字段值:
import fitz def extract_acroform_selected(pdf_path): selected = [] doc = fitz.open(pdf_path) for field in doc.widgets(): # 筛选选中状态的单选按钮 if field.field_type == fitz.PDF_WIDGET_TYPE_RADIOBUTTON and field.field_value == 1: selected.append(field.field_label) doc.close() return selected # 调用示例 print(extract_acroform_selected("acroform.pdf"))
内容的提问来源于stack exchange,提问作者riyagarg0597
相关产品推荐
相关产品推荐

