Camelot:从pdf中提取表格数据

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


工作要效率,大数据时代,获取信息也要效率,只用不断的造轮子,才能不断的提高效率,今天介绍一下一款可以直接从pdf格式的文档中提取表格中数据的工具,Camelot!!!


一、Camelot的介绍和安装

1. Camelot介绍

Camelot: 一个友好的PDF表格数据抽取工具

一个python命令行工具,使任何人都能很轻松的从PDF文件中抽取表格数据。

使用Camelot从PDF文档提取数据非常简单

  • Camelot允许你通过调整设置项来精确控制数据的提取过程
  • 可以根据空白和精度指标来判断坏的表格,并丢弃,而不必手动检查
  • 每一个表格数据是一个panda的dataframe,从而可以很方便的集成到ETL和数据分析工作流中
  • 可以把数据导出为各种不同的格式比如 CSV、JSON、EXCEL、HTML

2. Camelot的安装

camelot有三种安装方式:

  • pip 安装
  • conda安装
  • 源码安装
  1. pip 安装

pip install camelot-py[cv]

  1. conda安装

conda install -c conda-forge camelot-py

  1. 源码安装

git clone www.github.com/socialcopsd… cd camelot pip install ".[cv]"

注意:

如果后面导入camelot库包的时候,出现错误,可能是缺少Ghostscript包,用pip 安装即可。

3. 其他

源码参考文档: github.com/socialcopsd… 使用文档: camelot-py.readthedocs.io/en/master/

二、Camelot的使用

1. 快速入门使用

从一个pdf文件中提取出表格:

>>> import camelot
>>> tables = camelot.read_pdf('foo.pdf')
>>> tables
<TableList n=1>
>>> tables.export('foo.csv', f='csv', compress=True) # json, excel, html
>>> tables[0]
<Table shape=(7, 7)>
>>> tables[0].parsing_report
{
    'accuracy': 99.02,
    'whitespace': 12.24,
    'order': 1,
    'page': 1
}
>>> tables[0].to_csv('foo.csv') # 也可以提取成其他格式 to_json, to_excel, to_html
>>> tables[0].df # 获取一个pandas DataFrame!
复制代码

2. 详细说明

上面的例子的说明: 1、创建一个表格对象

>>> tables = camelot.read_pdf('foo.pdf')
>>> tables
<TableList n=1>   # 只检测到一个表格
复制代码

默认情况下,Camelot仅使用PDF的第一页来提取表。要指定多个页面,可以使用pages关键字参数:

>>> camelot.read_pdf('your.pdf', pages='1,2,3')
复制代码

也可以使用命令行执行相同的操作

camelot --pages 1,2,3 lattice your.pdf
复制代码

该pages关键字参数接受页面页码的逗号分隔的字符串。还可以指定页面范围 - 例如,pages=1,4-10,20-30或pages=1,4-10,20-end。

注意:

如果pdf文件是加密的表格,需要加入password参数,值为解密密码

>>> tables = camelot.read_pdf('foo.pdf', password='userpass')
>>>tables
<TableList n=1>
复制代码

命令行:

camelot --password userpass lattice foo.pdf
复制代码

目前,Camelot仅支持使用ASCII密码和算法代码1或2加密的PDF 。如果无法读取PDF,则抛出异常。这可能是由于未提供密码,密码不正确或加密算法不受支持。


2、查看表的形状(行和列),通过表格索引查看 我们可以使用其索引访问每个表。从上面的代码片段中,我们可以看到该tables对象只有一个表,因为n=1。让我们使用索引访问该表0并查看它shape。

>>> tables[0]
<Table shape=(7, 7)>
复制代码

3、打印解析报告。

>>> print tables[0].parsing_report
{
    'accuracy': 99.02,
    'whitespace': 12.24,
    'order': 1,
    'page': 1
}
复制代码

从解析的参数的评价标准可以得出,其准确性是很好的,空白较少,这意味着表格最有可能被正确提取。可以使用table对象的df属性将表作为pandas DataFrame访问。


4、打印出提取表格中的内容 数据格式是pandas DataFrane,因此用df访问

>>> tables[0].df
复制代码

在这里插入图片描述


5、导出表格中的内容 可以使用其to_csv()方法将表导出为CSV文件。或者可以使用to_json(),或方法表分别导出为JSON格式,Excel,HTML文件或SQLite数据库。方法如下:

  • to_csv()
  • to_json()
  • to_excel()
  • to_html()
  • to_sqlite()
>>> tables[0].to_csv('foo.csv')
复制代码

上面的1~5 步骤都可以通过命令行直接完成。

camelot --format csv --output foo.csv lattice foo.pdf
复制代码

使用的pdf例子的传送门:-->here

3. camelot两种表格解析(提取)方法

1、流解析(stream)

Stream可用于解析在单元格之间具有空格的表,以模拟表结构。它建立在PDFMiner的功能之上,即使用边距将页面上的字符分组为单词和句子。

  1. PDF页面上的单词根据其y轴重叠分组为文本行。
  2. 计算文本,然后用于猜测PDF页面上有趣的表区域。您可以阅读Anssi Nurminen的硕士论文,以了解有关此表检测技术的更多信息。[见第20,35和40页]
  3. 然后猜测每个表区域内的列数。这是通过计算每个文本行中的单词数模式来完成的。基于此模式,选择每个文本行中的单词以计算列x范围的列表。
  4. 然后使用位于当前列x范围内/外的单词来扩展当前列列表。
  5. 最后,使用文本行的y范围和列x范围形成表格,并且页面上找到的单词基于其x和y坐标分配给表格的单元格。

2、格子解析(lattice)

格子本质上更具有确定性,并且它不依赖于猜测。它可用于解析在单元格之间划分了行的表,并且它可以自动解析页面上存在的多个表。

它首先使用ghostscriptPDF页面转换为图像,然后通过使用OpenCV应用一组形态变换(侵蚀和膨胀)来处理它以获得水平和垂直线段

下面介绍处理的步骤: 1、检测分割线段 在这里插入图片描述

2、通过重叠检测到的线段并叠加"和"它们像素强度来检测线的交叉点在这里插入图片描述 3、通过再次重叠检测到的线段来计算表边界,这次是“或”它们的像素强度。 在这里插入图片描述 4、由于PDF页面的尺寸及其图像不同,因此检测到的表格边界,线条交叉点和线段将缩放并转换为PDF页面的坐标空间,并创建表格的表示。 在这里插入图片描述 5、使用线段和线交叉检测生成单元。 在这里插入图片描述 6、最后,页面上找到的单词将根据其x和y坐标分配给表格的单元格

三、高级使用

1. 处理背景线

1. 处理背景线

2. 可视调试

3. 指定表区域

4. 指定列表分隔符

5. 沿分隔符拆分文本

6. 标记上标和下表

7. 从文本中删除字符

8. 改善猜测的表区域

9. 改进猜测的表行

10. 检测短线

11. 在生成单元格中移动文本

12. 复制跨越单元格中的文本

13. 调整布局生成


四、命令行的使用

camelot --help 查看Camelot 参数使用:` 参数说明:

参数 完成参数 参数功能
-q --quiet TEXT 不输出日志和警告
-p --pages TEXT 页数范围,可以用都好分割符,或者页码范围,例如: 1,3,4 or 1,4-end
-pw --password TEXT 解密密码
-o -output TEXT 输出路径
-f --format [csv json
-z --zip 创建
-split --split_text 跨多个单元格拆分文本。
-flag --flag_size 根据字体大小标记文本。有用的检测超/下标。
-strip --strip_text TEXT 将字符串赋值给单元格之前,表格中的字符应该被删除
-M --margins 字符边缘、线边缘、单词边缘

猜你喜欢

转载自juejin.im/post/7095558424003346439