从 pdf 文件中复制表格,顺序是错乱的, pdf 表格中的文本选择顺序是怎么定义的呢?

360 天前
 sillydaddy
这个 pdf 文件,是建设银行储蓄卡的消费明细,表格形式的。里面的文本都可以选择,但鼠标框选文本时,整个的顺序几乎完全错乱:有时选不中某一个单元,有时选中了鼠标框之外的几行。即使我按住`option`键,选中特定的一列,拷贝出的文本的顺序也不是原始文档里的顺序。

开始我以为这是 pdf 的固有问题,可是我自己拿 macOS 上的 Number 做了一个同样的表格,然后导出为 pdf ,发现是可以有序选中文本的。不知道建行的 pdf 文件是用的什么工具生成的。

现在有点疑惑,pdf 中的表格,在选择它里面文本时,选中的顺序是依据什么而定的呢?我模糊记得网页里的表格,有时也有这个选中顺序的问题。
1484 次点击
所在节点    问与答
22 条回复
Huahuo
360 天前
我也有相似的需求,求教 python 有什么库可以顺序读 pdf 的表格吗?
zhangshine
360 天前
我对 pdf 有一点研究。PDF 其实是把字画上去,并不存在 word 里面的行或者段落的格式。所以你复制的时候的感觉和复制图片识别的文字的感觉差不多。
xomix
360 天前
pdf 实际上是一种虚拟打印指令把文字打印到虚拟纸张的指定位置。
所以当然可以:
a.虚拟打印一组表格文字到指定位置
b.虚拟打印将表格绘制为图片到指定位置
c.虚拟随机字符顺序将表格打印到指定位置

既然你无法通过 pdf 复制,那就考虑去水印和 ocr 。
sillydaddy
360 天前
@Huahuo 我现在还没到要用 python 读取那一步 🐶 。网上好像不少这种提取 pdf 表格的工具。
@zhangshine pdf 文档是不是分 2 种,其中 1 种是可以直接选文字的,一般纯文本转 pdf 就是这种。所以感觉跟图片 ocr 还是有点区别。
@xomix 文字是可以直接复制的,只不过顺序是乱的。ocr 也是会考虑的。不知道有 1#楼说的 python 工具可以读取 pdf 表格吗?
xomix
360 天前
@sillydaddy 你再认真看看我的回复,我想你的那个表格的输出方式是我例子里面的 c 例,也就是说你复制出来的结果就是正确结果,它就是随机乱序将文本输出至坐标位置实现的表格。
这种时候只能 ocr
yiyiwa
360 天前
python pdfplumber 这个库可以
sillydaddy
360 天前
@xomix 我明白你的意思了,就是说生成 pdf 的原始文本顺序就是乱的,但每个字符映射到 pdf 的位置是正确的,所以复制会有问题?按照这个说法,框选文字时,其实复制的是原始(顺序错乱)文本的一部分,比如计算出鼠标框左上角位置对应的文本,然后复制到鼠标框右下角位置对应的文本结束?这块框选复制的逻辑没有太明白。
zhangshine
360 天前
@sillydaddy 算是个 plus 版本,就是再画的基础上会添加一些结构信息,这样就和 word 差不多了。
chesha1
360 天前
我建议你直接截图给 chatgpt ,然后让他输出给你想要的格式,我打 latex 里的数学公式就是这么做的,而且准确率很高
xomix
360 天前
@sillydaddy pdf 你没做过深入理解吧。
我简单说一下,方便让你明白,很多东西是大致这样不是严格的原理。

pdf 是把 图像 或 文字 按照固定格式渲染的技术,有点儿像 htrml 。

当他输出一段文字时候,可以对每一个文字设置其定位属性,但是这段文字本身是连续的文本。因此你可以选择这段文字,但当你选择了这段文字时,能够复制的是文本段的实际顺序而不是展示顺序,所以看起来是正常顺序,但是复制后是乱序。
sillydaddy
360 天前
@zhangshine 明白了
@chesha1 gpt4 吧,我还冇有呢

@xomix 举个具体的例子,如果 pdf 打印输出的结果是"0123456789",而生成这个打印结果的原始文本是"5678901234",也就是说,「文本索引」->「打印位置」的映射关系是 0->5, 1->6, 2->7, 3->8, 4->9, 5->0, 6->1, 7->2, 8->3, 9->4 。那么当我在 pdf 中,用鼠标从"0123456789"当中的"0"字符,也就是打印位置是 0 的地方,开始往后框选三个字符,框选的位置分别是 0,1,2 ,那么从根据「文本索引」->「打印位置」的关系,反映射回去,得出实际被选中的字符是"567"对吗?

如果是(像你说的)直接建立的是「文本字符」->「打印位置」的映射,也就是说"0"->0, "1"->1, ... "9"->9 ,那么鼠标框选,根据位置反映射到字符时,就不会出现问题了。

你能根据这个例子解释一下吗?因为#10 楼的逻辑我没太理解。
xomix
360 天前
@sillydaddy
以下是一段伪代码,肯定不是 pdf ,只是方便你理解。

打印代码段如下
···
文本段开始
[绝对位置 0 ,3]1
[绝对位置 0 ,0]2
[绝对位置 0 ,9]3
[绝对位置 0 ,5]4
[绝对位置 0 ,7]5
[绝对位置 0 ,6]6
[绝对位置 0 ,1]7
[绝对位置 0 ,2]8
[绝对位置 0 ,4]9
[绝对位置 0 ,8]0
文本段结束
···

你看到的展示将会是
2781946503

因为是组文本,当你选择时候,这些文字会都被你选中,但是你复制时会复制无格式信息的文本段内容
1234567890
sillydaddy
360 天前
@xomix 你#12 楼说到的这一层面我是理解的。我不理解的是,如果#12 楼的例子中,只选中 10 个字符中的 3 个字符,会发生什么?怎么根据鼠标框选的位置,反推得到框选选中的字符。想了解这个,是因为根据它可以推理出在 pdf 中选择表格里面的一部分内容时,会发生什么。
不过大概的意思我知道了,谢谢你耐心的解释。
Huahuo
360 天前
@yiyiwa 多谢
@sillydaddy python pdfplumber 这个好用
kumakichi
360 天前
一个猜想,
截图 丢给 gpt 生成 csv 格式的?
然后复制回来?
013231
360 天前
findsomeone
360 天前
除了 py 那个库,如果你用 iphone 的话,截图放相册再识别复制也可以~~
xomix
360 天前
@sillydaddy 不同的 api 处理方式不一样,这个没有一概而论的。不过大致都是选择三个文本,至于是选择原始数据三个文本还是选择实际现实数据三个文本,最后按照原始文本顺序排列。
xomix
360 天前
@sillydaddy 这还是理想情况,如果说一开始 pdf 就不想让你复制,生成的时候可能用多组随机顺序文本按照指定位置输出,你复制的文本就更乱了。
sillydaddy
360 天前
@yiyiwa
@Huahuo
@013231
感谢。看了下 pdfplumber 这个库不错,还可以可视化 debug 。camelot 也不错,也可以可视化 debug ,文档也挺详细。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/996128

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX