PDF 提取文本

把 PDF 里的文字捞出来,按原来的版面排回一行一行,而不是一大坨粘在一起的字符。

可以拖文件进来。取字在本机完成,PDF 不会上传;扫描件没有文字层,提取结果会是空的,这是文件本身的性质。

选择 PDF 后开始提取文字

关于 PDF 文字提取

为什么必须自己拼行。PDF 里没有「行」这个概念,只有一个个文字块,每个块带自己的坐标和字体。同一句话可能被切成十几个块,甚至一个字一个块,全看生成这份 PDF 的软件怎么排版。所以提取文字必须按 y 坐标把块归到同一行、按 x 坐标确定顺序,再根据字间距判断中间有没有空格。直接按顺序拼接的结果常常是一整段没有换行的文字,或者单词之间全粘在一起。

扫描件提不出文字。扫描仪和拍照生成的 PDF,每一页其实就是一张图片,里面根本没有文字块,任何文本提取工具都读不出内容。判断方法很简单:提取结果是空的,或者整页只有几个字符(页眉页脚)。这种情况只能先做 OCR(光学字符识别),需要额外的工具,浏览器里跑不动高质量 OCR。有些 PDF 是「图片上盖了一层不可见的文字」,那是有 OCR 层的扫描件,可以正常提取。

表格和多栏排版会被打散。表格里每格文字都是独立的块,按坐标拼行只能还原出「一行里的内容」,列与列之间通常靠制表符或空格区分,单元格合并、跨页表格都会变形。双栏排版的论文更麻烦,两栏的 y 坐标是交错的,可能被拼到同一行里。要求高的场景(论文、财报、表格)应该用专门的版面分析工具,比如 pdftotext 的 -layout 模式、camelot、或者商业化的文档解析 API。

文字看起来正常也可能提不出来。有些 PDF 用的字体没有嵌入,或者做过子集化处理,还可能故意把字符编码打乱(防复制)。表现出来就是提取出一堆乱码或者方框。另外中文 PDF 常见「一个字对应多个 Unicode 码位」的情况,提取出来会出现多余的空格或错字。这类问题在源文件层面,工具没法修。

提取出来能干什么。常见的用法有:把合同、论文、说明书转成可搜索可编辑的文本;批量抽取 PDF 里的邮箱、金额、编号做统计;给 PDF 做全文检索;或者把文字喂给翻译工具。如果只是想复制一小段,直接在 PDF 阅读器里选中复制更快;整篇提取适合「页数多、需要再加工」的场景。

版面还原做到了哪一步

同一行内的文字块按 x 坐标从左到右拼,块与块之间的空隙超过字号的四分之一才补空格,这样「单 位」这种被拆开的词组不会变成「单 位」之外的样子,而真正分开的单词也不会粘成一团。空隙超过字号的 1.2 倍时写成制表符,对应表格里的列和双栏排版之间的间隔——不过要清楚这只是「看起来像」,不保证粘回 Excel 还能对齐。

段落之间的空行是可选的:打开之后,工具会先算出这一页里最小的行距当作正常行距,超过它 1.8 倍的间隙就补一个空行。这样做在正文段落明显的文档上效果不错,但在行距本来就忽大忽小的排版(比如带大量公式的论文)里会多出一些空行,发现不对可以关掉这个选项重新提取。

为什么要单独加载解析模块。PDF 的解析和渲染由 pdf.js 完成,它带一份独立的后台线程脚本(worker)。这个脚本体积约一兆,只有在真正上传 PDF 时才会下载,进页面看说明不会付这份流量。worker 跑在后台线程里,所以解析几百页的文件时页面还能响应滚动和按钮,只是渲染每一页时主线程会短暂变忙。

文件不会离开这台电脑。整个解析、渲染、取字的过程都在浏览器本机进行,没有任何一步把文件发到服务器。断网之后这些工具照样能用(前提是页面已经打开、worker 已经加载过)。如果你在公司内网处理涉密文件,可以用浏览器开发者工具的网络面板自己确认:除了页面本身的静态资源,不会有任何上传请求。

大文件的实际限制。整个 PDF 会被读进内存再交给 pdf.js 解析,页数越多、里面的图片越多,占用越大。一百页以内的普通文档完全没问题;超过五百页或几百兆的扫描件,浏览器可能变卡甚至被系统杀掉标签页。这种情况更稳的做法是用命令行的 pdftotext、pdftoppm 或 qpdf 处理,它们没有浏览器的内存和画布上限。