我想刮掉PDF tables which span across multiple pages . 我尝试了很多东西,但最好的似乎是 pdftotext -layout
为advised here . 问题是生成的文本文件不易使用,因为表格布局在页面之间不同,因此列不对齐 . 另请注意以"Solsonès"开头的行中缺少的值:
TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012
COMARCA CODI i NOM EMA GEN FEB MAR ABR MAI JUN JUL AGO SET OCT N
Alt Camp VY Nulles 7,5 5,5 10,9 12,3 16,7 21,6 22,3 24,4 20,1 15,9
Alt Camp DQ Vila-rodona 7,9 5,6 11,0 12,0 16,6 21,6 22,0 24,3 19,9 15,8
Alt Empordà U1 Cabanes 8,2 6,5 11,7 12,6 17,5 22,0 23,1 24,4 20,4 16,6
Alt Empordà W1 Castelló d'Empúries 8,1 6,4 11,6 12,9 17,0 21,1 22,0 23,4 20,1 16,4
[...]
TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012
COMARCA CODI i NOM EMA GEN FEB MAR ABR MAI JUN JUL AGO SET OCT
Baix Empordà DF la Bisbal d'Empordà 6,6 5,3 10,9 12,6 17,2 21,9 22,9 24,6 20,3 16
Baix Empordà UB la Tallada d'Empordà 6,1 5,2 10,7 12,3 16,6 21,3 22,2 23,8 19,7 15
Baix Empordà UC Monells 6,1 4,6 9,9 11,4 16,5 21,7 23,0 24,5 19,6 15
[...]
TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012
COMARCA CODI i NOM EMA GEN FEB MAR ABR MAI JUN JUL AGO SET OCT
[...]
Solsonès CA Clariana de Cardener 4,6 3,3 10,3 10,2 16,7 22,3 d.i.
Solsonès Z8 el Port del Comte (2.316 m) -0,9 -6,3 -0,2 -2,0 5,3 10,5 10,9 13,8 7,8 4,2
Solsonès VO Lladurs 3,0 2,6 9,5 9,0 15,3 21,4 21,6 24,3 17,5 13,0
Solsonès VP Pinós 3,0 1,6 8,9 9,2 15,4 21,1 21,3 23,8 17,6 13,3
Solsonès XT Solsona d.i. 24,3 18,0 13,5
Tarragonès VQ Constantí 7,9 6,0 11,2 13,1 17,1 21,9 22,6 24,6 20,6 16,6
Tarragonès XE Tarragona - Complex Educatiu 10,2 7,8 12,3 14,6 18,3 23,0 24,2 26,2 23,0 * 18,4
Tarragonès DK Torredembarra 9,7 7,7 12,3 14,3 17,9 22,8 24,3 26,2 22,7 18,5
Terra Alta WD Batea 6,3 5,0 11,2 12,1 18,3 23,0 23,3 25,5 20,2 15,9
Terra Alta XP Gandesa 6,6 5,2 11,2 12,2 18,1 22,9 23,4 25,6 20,4 16,0
complete file for download - UTF8
So, this output is not very easy to parse. What other approach is available?
似乎我使用的每个工具只能提取有关表格单元格布局的信息,但它不会提取属于特定列的信息 . 如果单元格为空,则非常明显 - 空单元格不在输出中,只有它们的布局才能获得非空"cells" . Does the PDF itself contain this tabular information? 如果没有,搜索将提取它的工具没有意义 .
Paid solutions are not out of question ,因为它可能最终比我投入几个工作日更便宜......
我尝试过的:
-
复制粘贴 - 使缺失值出现问题(第5页)
-
从Acrobat保存为文本(比复制粘贴更糟糕的结果)
-
在Excel中打开作为外部数据源 - 将无法识别该表
-
http://www.pdftoexcel.org/以及他们对Able2Extract的审判 - they messed up some columns . 他们在预览中正确识别了列,但在excel输出中它们被搞砸了
-
http://www.pdftoword.com/ - 只需接收我的电子邮件,绝不发送任何内容
在 scraperwiki http://schoolofdata.org/2013/06/18/get-started-with-scraping-extracting-simple-tables-from-pdf-documents/ seems very complicated especially for non-python users 和https://scraperwiki.com/使用python的 -
不是免费的
-
我遇到过几个像pdftables这样的python库,但是对于像我这样的非python开发人员来说它们并不容易使用(我甚至无法运行这些东西) . 有没有更简单的方法来完成任务?
-
我试图在R中使用
tm
库作为recommended here,但是I have encountered some problems
编辑:Ian推荐的Cloud SDK . 我注册但我绝对不知道从哪里开始 - 如何上传页面,识别它们等:
7 回答
好吧,我对此采取了一些措施,我认为这会有所帮助,虽然我不确定你想要的最终输出是什么样的 . 我很乐意在这方面做更多的工作,所以请告诉我你是否需要帮助 .
我开始从CNET下载PDF to Text application .
安装后,我检查了这些设置:
这里的重要部分是我们正在使用物理布局选项 .
这给了我们看起来像这样的输出:
您可以看到列的排列更好,但我们也有 Headers 和页码 . 此列
COMARCA
和i NOM EMA
列的长度也不尽相同 . 我们想将其标准化为固定宽度列 .我编写了一个Perl程序来对其进行规范化,它还将表格与相同的 Headers 组合在一起,并且只在顶部打印 Headers . 它创建一个输出文件夹,其中包含 Headers 为文件名的所有文件 .
这是代码:
输出中仍然存在一些不完善之处(当你运行它时你会看到这些),但我想得到一些关于哪种输出最适合你的反馈 . 我们肯定可以做更多改进代码!输出目录树如下所示:
文件可能如下所示:
Headers 只在顶部,所有列都排列在一起 . 这个是
TEMPERATURA MITJANA MENSUAL ( ºC ) - 2012
.我一直在考虑将更多的输出上传到文件托管网站,但我不知道哪个是好的,建议?
希望这可以帮助你Tomas!
编辑:AMPLITUDTÈRMICAMÀXIMAMENSUAL(ºC) - 2012年缺少参赛作品的示例:
更新
更新了用于处理输入文件的脚本:
这个结合了d.i.在下一行 .
输出采用带分号分隔符的csv格式 .
这是一个R解决方案,但它并非没有缺陷 .
第1部分:设置步骤
第2部分:使用read.fwf获取数据
第3部分:它有用吗?
它 sort of 工作 . 但是,您的输入文件并不完美,这意味着仍然会有很多清理工作 . 例如,PDF中的某些列似乎有多个值 . 不知道你将如何对这些进行任何分析 .
希望上面代码中的注释可以帮助您开始找出如何以更好的方式抓取数据 .
更新:仅提取数据
在上面的"Part 1"之后继续,这是一个依赖于(喘气)Excel的解决方案 . 基本的想法是如果你将文本导入固定宽度,Excel实际上可以很好地检测列断点的位置 .
因此,我们使用R将文本分解为单独的页面,每页一个文件,只有数据(不是列名或行名,在所有数据集中大致相同) .
有了这个,这是最后一个R步骤:
让我们打开文件“temp_9.txt”,这是一个缺少列的文件:
^^确保选择“固定宽度” - 默认情况下应该是该文件没有分隔符 .
^^ Excel显示预览列的位置 .
^^我已经突出显示了“问题行”,以便您了解它是如何运作的 .
在过去,我使用了pdftohtml,它可用于生成xml,描述为here . 列通常分离得很好,因此您可以使用定位来提取列 .
我写了pdftables的很大一部分,为不透明道歉!对于您显示的文档的某些页面,它可以正常工作,例如第2页给出了此回复底部的输出 . 例如,对于其他页面,它会在第33页上失效 . 这里的问题是在一个列 Headers 下有两个数字,它们被pdftables粘在一起 . 在任何一种情况下,"COMARCA, CODI i, NOM EMA"列都不会分开 . 你可以在GitHub上提交pdftables的问题,我现在还没有积极地处理它 . 它可以通过pip install获得 .
如果你想去商业路线那么Abbyy FineReader是非常好的,他们会产生一个cloud SDK,这将给你30个左右的免费页面 . 他们有多种语言的示例代码,但他们的支持并不是很好 .
unicode问题归结于我的开发环境(Spyder) .
如果您对深入研究Python或其他基于代码的解决方案持谨慎态度,那么针对少量pdf的快速而肮脏的解决方案的完全不同的方法是将任务外包给MechanicalTurk .
每列拥有多个用户允许您仔细检查提交的答案,并且您还可以发布生成的.csv表并为工作人员可以找到的每个错误支付大量(例如,5美元) . 通常最终会比您或其他人编写解决方案的时间更便宜 .
虽然使用
pdftotext
时页面的布局不同,但请注意,各个页面上的列 Headers (COMARCA,CODI等)似乎与该页面上的数据对齐 .此外,您的pdf中有许多不同类型的数据 - 风向,风力,湿度,降水等. So not only does the layout differ across pages for the same data, but the layout differs because there are different data sets as well.
只是为了完整性 - 原始PDF中存在"Solsonès"(作为一个示例)的缺失数据 . 似乎
pdftotext
做了一个合理的工作 - 缺少的数据是空白,就像在原始PDF中一样 .因此,保留
pdftotext
并将页面(由换页符分隔)视为列数据并使用_1408826解析,这可能是有意义的,如下所示:How to efficiently parse fixed width files?
实现此功能的一种方法是检测换页,查找以"COMARCA"开头的下一行,并使用该行中的间距设置
struct
的列 .为此构建索引的努力(可能是格式的变化与不同的子报告有关 . 这些似乎都适用于加泰罗尼亚:
parens和破折号干扰了grepping . 所以试图进入一个表单,其中这些值可用于通过
grep(val, txt)
识别页面 Headers 位置成功,删除"\\(.+$"
匹配单个异常(我决定修复"by hand":因此,寻找结束页面的标记看起来像4个空行是可靠的
删除了所有“Ô因为他们正在创建非固定宽度列:
有趣的是,我的文本编辑器现在显示"à" 's where the 1408838 '曾经出现过 . 此时,可以将页面类型中的页面从pagedivs 4开始循环到4个空行的位置,并使用'utils'包中的
read.fwf
. 剩下要支持的是一个布局定义,你说你已经有了一个句柄,但也可以使用pkg:gsubfn的strapply或正则表达式解决方案来推断 .寻找开发正则表达式解决方案的方法:
很明显,这些页面分为两类:数字列数为12-14的页面和数字列数为23-28的页面 . 我原以为这会有所不同,但我猜“任何”专栏抛出了我的期望 .
很明显,原始Excel电子表格由使用不同列宽的不同表格组成 .
因此PDF表格也使用不同的列宽 . 如果查看PDF,您可以看到以下页面范围组,每个页面范围具有相同的列宽 . 每个小组还描述了不同的内容,从每个小组的起始页面的更改 Headers 可以看出(即使无法理解西班牙语,我也可以识别这些差异):
第2-6页(5页)
第7-11页(共5页)
第12-16页(5页)
第17-21页(5页)
第22-26页(5页)
第27-31页(5页)
第32-36页(5页)
第37-41页(5页)
第42-46页(5页)
第47-51页(5页)
第52-56页(5页)
第57页58(2页)
第59-62页(4页)
第63-67页(5页)
第68-72页(5页)
第73-76页(4页)
第77-80页(4页)
第81-84页(4页)
第85-88页(5页)
第89-93页(5页)
第84-98页(5页)
第99-103页(5页)
第104-107页(4页)
第108页109(2页)
第110页111(2页)
第112页113(2页)
最后,第114页(仅限1页)
因此,您可以让
pdftotext
通过这些页组提取表数据 . 如果结果不是每个页面范围内的完美对齐列,则必须逐页提取表 . 这些应该很容易导入Excel作为"fixed-width"表数据 .为了向您展示一个示例(使用Poppler的
pdftotext
版本创建):pdftotext \ -layout \ -enc UTF-8 \ -f 22 -l 26 \ -nopgbrk \ -x 20 -y 82 \ -W 810 -H 450 \ EMAtaules2012.pdf \ -
-f 22 -l 26 :
这告诉工具将页面22提取为范围中的第一个,将第26页提取为最后一个 .
-nopgbrk :
告诉该工具不插入分页符 .
-x 20 -y 82 :
设置从中提取表数据的区域的左上角(以像素为单位) . 注意,我在这里使用了这些值,它们也排除了列 Headers ,而不仅仅是页眉和表名 .
-W 810 -H 450 :设置用于表数据提取的区域的宽度和高度(以像素为单位) .
请注意,如果您使用XPDF的pdftotext版本(可在www.foolabs.com/xpdf/download.html上找到),则不支持-x,-y,-W和-H的命令行选项 . 但是如果你使用-table而不是-layout与XPDF-pdftotext,那么结果应该是相似的(但你仍然需要手动删除页面和列 Headers ) .
上面的命令为你提供了这个输出(我只显示前两页的输出,宽度跳跃在页面边框的正确位置,
Baix Ebre
条目后面的两行):如果您知道如何正确操作文本编辑器,则可以非常轻松快速地修复此文本输出,因此可以顺利地通过Excel导入...