工具分享 | PDF文档解析工具PyMuPDF

1 需求描述

最近工作需要从PDF文档中按照章节解析出对应的文本和图片(后续可能还会有表格),经过调研,找到了一个功能强大的解析工具MuPDF,对应的Python包是PyMuPDF。本篇博客记录使用它来实现具体功能。

官方文档:https://pymupdf.readthedocs.io/en/latest/index.html

2 利用书签中标题划分章节

在PDF中,点击书签或者目录页中具体一个标题时,文档页面会跳转到对应的章节,“跳转”的实现说明了其背后有一套机制(交叉引用),记录了各级标题和正文页面的对应关系。

PyMuPDF解析书签中各层级标题的接口为Document.get_toc(),该接口可以返回书签的层级、名称、点击它跳转到的页码及具体到目标页的哪个位置。

  • 接口介绍

    get_toc(simple=True/False)
    
    # 参数simple=True时,返回简单版本的各级目录,包括[标题层级, 标题名称,跳转到的页码],例如:
    [
    2,             // 第二级
    '旅行规划',     // 名称
    9,             // 对应正文的第9(该字段index从1开始)
    ]
    
    # 参数simple=False时,在跳转到的页码基础上,增加了'to'指向跳转页具体的坐标点(x, y)
    [2, '用户手册介绍 ', 9, 
    {'kind': 1, 'xref': 3112, 
    'page': 8, 'to': Point(43.937, 29.877015), 
    'zoom': 0.0, 'collapse': False
    }]
    
  • 详细文档


     

利用对书签的解析,获取到了:
(1)文档的层级关系: 包含多少第一级大标题、每个第一级标题下又有多少二级标题,以此类推可以获取完整的文档结构;
(2)每一级标题在正文中的页面范围,例如从第3页(43,40)到第5页的(253, 400)。

因此可以实现按照章节的拆分。

3 基于章节的文本解析

划分章节后,每一章节在正文中的位置由:起始页面、起始页面的坐标、结束页面、结束页面坐标描述,例如,start_page = 5, (start_x = 43, start_y = 36),end_page = 8, (end_x = 134, end_y=238)。

  • 起始页和结束页只需要解析该章节范围内的文字,选择使用Page.get_textbox()方法获取矩形框rect范围内的文字:


     

     
  • 中间页需要在获取页面全部范围内的文字后,过滤页眉和页脚。因此选择使用Page.get_text(“blocks”)方法按块获取该页内所有段落的坐标、文字内容及类型(文本、图片),然后根据坐标过滤掉页眉、页码等不需要的文字内容。


     
  • 文本乱序问题:作者插入顺序可能不是按照阅读顺序,导致解析出来的文字出现了乱序,例如第5行的文字解析出来之后在第10行文字的后面;解决乱序问题主要是通过设置参数sort=True(默认为False),将解析的文本按照坐标排序,来获得按照自然阅读顺序的文本。

  • 单双列布局问题:双列布局的页面,根据页码的坐标来区分是左侧还是右侧。

4 扫描PDF解析

图片扫描成的PDF并不是按照PDF标准形成的文档,没有包含文本信息,按照 3 中的方法获取的文本是空的。

其中一种解决方法是使用OCR获取图片中的文本:

(1)OCR的工具有多种,如PyMuPDF文档提及的OCRMyPDF(免费)。选择OCRMyPDF的话需要配置依赖的两个软件:tesseract和gs,并且由于OCRMyPDF默认的文字识别模型支持英文,在中文情况下需下载对应的中文识别模型。








 

(2)OCR获取文字会存在识别错误的情况,要考虑识别错误对后续处理是否会造成影响。

5 基于章节的图片解析

  • 使用Page.get_image_info(hashes=False, xrefs=False)接口获取图片的元信息,包括图片的原始宽高、嵌入到pdf后的bbox以及交叉引用的序号xref;获取元信息主要是为了使用位置信息来判断图片属于哪个章节;


     
  • 然后使用Document.extract_image(xref)根据元信息中的xref获取存储的图片信息并保存;


     

6 小结

  • 最近解析文档最大收获在于:要明确自己的需求,根据需求去选择工具;PyMuPDF提供的接口功能很强大,面对布局多样的文档,不要急于动手,可以多查阅官方文档寻找更合适的接口,在此基础上设计方案。
  • 分享发现的宝藏博客,博主的系列文章记录了使用PyMuPDF将pdf文档转为word的过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/63817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript 生成 16: 9 宽高比

这篇文章只是对 for 循环一个简单应用,没有什么知识含量。 可以跳过这篇文章。 只是我用来保存一下我的代码,保存在本地我嫌碍眼,总想把他删了。 正文部分 公式:其中 width 表示宽度,height 表示高度 16 9 w i d t…

sql各种注入案例

目录 1.报错注入七大常用函数 1)ST_LatFromGeoHash (mysql>5.7.x) 2)ST_LongFromGeoHash &#xff08;mysql>5.7.x&#xff09; 3)GTID (MySQL > 5.6.X - 显错<200) 3.1 GTID 3.2 函数详解 3.3 注入过程( payload ) 4)ST_Pointfromgeohash (mysql>5.…

【python使用 Pillow 库】缩小|放大图片

当我们处理图像时&#xff0c;有时候需要调整图像的大小以适应特定的需求。本文将介绍如何使用 Python 的 PIL 库&#xff08;Pillow&#xff09;来调整图像的大小&#xff0c;并保存调整后的图像。 环境准备 在开始之前&#xff0c;我们需要安装 Pillow 库。可以使用以下命令…

【学习笔记】fhq Treap实现文艺平衡树

没有学习过 fhq Treap 的可以看我上一篇文章&#xff0c;看过的建议去再看看分裂和合并操作 回顾 在上一篇文章中提到&#xff0c;fhq Treap 可以支持比较多的操作&#xff0c;文艺平衡树就是其中一种&#xff0c;其实就是可以实现区间操作&#xff08;翻转&#xff09;的平衡…

面试官问我MySQL和MariaDB的联系和区别,这我能不知道?

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

MQTT,如何在SpringBoot中使用MQTT实现消息的订阅和发布

一、MQTT介绍 1.1 什么是MQTT&#xff1f; MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议&#xff09;&#xff0c;是一种基于发布/订阅&#xff08;publish/subscribe&#xff09;模式的“轻量级”通讯协议&#xff0c;该协议构建于…

广场舞音乐制作软件,FL Studio怎么做广场舞音乐

广场舞一直以来都是许多人日常的消遣方式之一&#xff0c;富有节奏感的音乐能够让人沉浸其中&#xff0c;这也说明了音乐的重要性。那么如果我们想自己制作一个广场舞风格的音乐&#xff0c;需要具备哪些条件呢&#xff1f;今天我们就来说一说广场舞音乐制作软件&#xff0c;FL…

大数据专业毕业能从事什么工作

大数据从业领域很宽广&#xff0c;不管是科技领域还是食品产业&#xff0c;零售业等都是需要大数据人才进行大数据的处理&#xff0c;以提供更好的用户体验&#xff0c;优化库存降低成本预测需求。 大数据开发做什么&#xff1f; 大数据开发分两类&#xff0c;编写Hadoop、Spa…

无涯教程-JavaScript - POISSON函数

POISSON函数取代了Excel 2010中的POISSON.DIST函数。 描述 该函数返回泊松分布。泊松分布的常见应用是预测特定时间的事件数。 语法 POISSON(x,mean,cumulative)争论 Argument描述Required/OptionalXThe number of events.RequiredMeanThe expected numeric value.Require…

C# XML格式转换字典

public static Dictionary<string, string> GetXmlStr(string xmlStr) //获取 xml 字符串 转字典 { Dictionary<string, string> kv new Dictionary<string, string>(); XmlDocument x new XmlDocument(); …

【每日一题】66. 加一 ,1822. 数组元素积的符号,682. 棒球比赛

66. 加一 - 力扣&#xff08;LeetCode&#xff09; 给定一个由 整数 组成的 非空 数组所表示的非负整数&#xff0c;在该数的基础上加一。 最高位数字存放在数组的首位&#xff0c; 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外&#xff0c;这个整数不会以零开头…

RISC-V交叉工具链riscv-gnu-toolchain编译

文章目录 1、下载2、编译1. 依赖安装2. 编译 3、运行 1、下载 $ sudo apt-get install git wget build-essential $ git clone https://github.com/riscv-collab/riscv-gnu-toolchain $ git checkout 2023.06.02注意上面 clone 的仓库&#xff0c;我们称其为构建脚本仓库&…

K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系

写在前面 博文内容整体结构为结合 华为云云原生课程 整理而来,部分内容做了补充课程是免费的&#xff0c;有华为云账户就可以看&#xff0c;适合理论认知&#xff0c;感觉很不错。有需要的小伙伴可以看看&#xff0c;链接在文末理解不足小伙伴帮忙指正 对每个人而言&#xff0c…

Linux之web服务器

目录 www简介 常见Web服务程序介绍 服务器主机 主要数据 浏览器 网址及HTTP简介 URL http请求方法 状态码 MIME&#xff08;Multipurpose Internet Mail Extension&#xff09; www服务器的类型 静态网站 动态网站 Apache服务的搭建 Apache的安装 准备工作 htt…

在支付宝中 下载社会保险参保证明 方法

这里 我们打开支付宝 选择 市明中心 然后选择 社保 这里 在社保查询下 找到 个人社会参保证明查询 这里 选择好自己的省市区 文件就会出现在下面了 我们直接点击这个文件进入 下面就会有下载的选项了

深度解析 PostgreSQL Protocol v3.0(一)

引言 PostgreSQL 使用基于消息的协议在前端&#xff08;也可以称为客户端&#xff09;和后端&#xff08;也可以称为服务器&#xff09;之间进行通信。该协议通过 TCP/IP 和 Unix 域套接字支持。 《深度解析 PostgreSQL Protocol v3.0》系列技术贴&#xff0c;将带大家深度了…

IO面试题整理

1.同步/异步&#xff0c;阻塞/非阻塞是一样的概念吗&#xff1f; 不一样。 阻塞/非阻塞说的是调用者。调用者需要等待就是阻塞&#xff0c;不需要等待就是非阻塞。 同步/异步说的是被调者通知调用者的方式。被调者执行完成后再恢复调用者是同步。被调者立即告诉调用者收到求…

MySQL如何查找某个字段值相同的数据

当我们想要查找MySQL中某个字段值相同的数据&#xff0c;但我们又不知道这个数据的值是什么的时候该如何操作呢&#xff1f; 在我的数据表中有单词表以及对应的详细信息表&#xff0c;如果两张表是以单词作为逻辑上的外键时&#xff0c;查询单词详细信息操作就可以根据word值进…

无涯教程-Android - Spinner函数

Spinner允许您从下拉菜单中选择一个项目 例如。使用Gmail应用程序时,将显示如下所示的下拉菜单,您需要从下拉菜单中选择一个项目。 Spinner Example 示例 本示例演示计算机的类别,您需要从类别中选择一个类别。 以下是修改后的主要Activity文件src/com.example.spinner/Andr…

Java--静态字段与静态方法

1、静态字段 如果将一个字段定义为static&#xff0c;每个类只有一个这样的字段。而对于非静态的实例字段&#xff0c;每个对象都有自己的一个副本。 例如&#xff1a; class Employee {private static int nextId 1;private int id;... }其中&#xff0c;每一个Employee对…