使用pdfminer.six提取PDF行序混乱,求解决方法
解决pdfminer.six提取PDF行序混乱的方案
问题重现
原PDF为一道选择题,使用pdfminer.six解析后文本顺序混乱(如选项4、5被插入到选项3与答案提示之间),输出结果如下:
Nr 48. Promująco na rozwój chorób alergicznych i wystąpienie objawów alergii działa zwiększenie aktywności/ilości: 1) limfocytów Th1; 2) limfocytów Th2; 3) limfocytów Th17; Prawidłowa odpowiedź to: B. tylko 2. A. 1,4. 4) IL-5. 5) IL-12. C. 1,3. D. 2,4. E. 3,5.
可行解决方法
1. 调整pdfminer布局分析参数
pdfminer默认布局分析对复杂排版处理不佳,可通过修改LAParams参数强制按垂直位置排序文本块:
from pdfminer.high_level import extract_text from pdfminer.layout import LAParams laparams = LAParams( line_overlap=0.5, char_margin=2.0, line_margin=0.5, word_margin=0.1, boxes_flow=0, # 设为0表示严格按垂直位置排序,符合从上到下的阅读顺序 detect_vertical=False ) text = extract_text("目标PDF文件路径", laparams=laparams) print(text)
重点关注boxes_flow:0代表优先按文本块垂直位置排序,若为分栏PDF可设为1(按水平顺序)。
2. 自定义文本排序逻辑
若默认参数仍无效,可直接获取页面布局元素,按坐标手动排序:
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage from io import StringIO def extract_text_sorted(pdf_path): rsrcmgr = PDFResourceManager() retstr = StringIO() laparams = LAParams() device = TextConverter(rsrcmgr, retstr, laparams=laparams) fp = open(pdf_path, 'rb') interpreter = PDFPageInterpreter(rsrcmgr, device) sorted_text_total = "" for page in PDFPage.get_pages(fp): interpreter.process_page(page) # 获取当前页面的布局对象 layout = device.cur_item # 按文本块顶部y坐标从高到低排序(PDF原点在左下角,y值越大位置越靠上) text_blocks = sorted(layout._objs, key=lambda x: (-x.y1, x.x0)) # 拼接有效文本块 page_text = '\n'.join([obj.get_text().strip() for obj in text_blocks if hasattr(obj, 'get_text')]) sorted_text_total += page_text + '\n' fp.close() device.close() retstr.close() return sorted_text_total # 使用示例 result = extract_text_sorted("目标PDF文件路径") print(result)
该方法直接操作PDF布局元素,确保文本按视觉上的从上到下、从左到右顺序排列。
3. 替换工具尝试
如果pdfminer始终无法适配该排版,可切换工具:
- PyMuPDF(fitz):对复杂排版的原生支持更好,默认排序更贴近视觉顺序:
import fitz doc = fitz.open("目标PDF文件路径") full_text = "" for page in doc: full_text += page.get_text() print(full_text)
关于转HTML效果差的说明
PDF转HTML时每个单词单独被span包裹,是因为原生PDF中每个字符的位置独立存储,转译时会按字符坐标生成标签,这种情况难以直接优化,不如直接调整文本提取的排序逻辑。
内容的提问来源于stack exchange,提问作者mik.ro
相关产品推荐
相关产品推荐

