python语言Camelot库: 人类的 PDF 表提取

一、介绍

官方介绍Camelot是一个 Python 库,可以帮助您从 PDF 中提取表格!需注意的是Camelot 仅适用于基于文本的 PDF,不适用于扫描文档。针对从长 PDF 文档中提取表格期间,RAM 使用量会显着增加。可以通过将提取分成块,并在每个块的末尾将提取的数据保存到磁盘来减少长 PDF 的内存使用量。
那么为何选择Camelot来进行PDF表的提取了?
Camelot的优点:
1、可配置性:Camelot 通过可调整的设置让您控制表格提取过程。

2、指标:您可以根据准确性和空白等指标丢弃坏表,而无需手动查看每个表。

3、输出:每个表都被提取到一个pandas DataFrame中,它可以无缝集成到ETL 和数据分析工作流中。您还可以将表格导出为多种格式,包括 CSV、JSON、Excel、HTML、Markdown 和 Sqlite。

二、安装

安装依赖项Ghostscript

特定于操作系统的说明

#Ubuntu
$ apt install ghostscript python3-tk
#MacOS
$ brew install ghostscript tcl-tk
#Windows
对于 Ghostscript,您可以在他们的下载页面获取安装程序。对于 Tkinter,您可以从 ActiveState下载ActiveTcl 社区版。
验证Ghostscript 是否安装成功

打开 Python REPL 并运行以下命令:

#对于 Ubuntu/MacOS:
from ctypes.util import find_library
find_library("gs")
"libgs.so.9"
#对于 Windows:
import ctypes
from ctypes.util import find_library
find_library("".join(("gsdll", str(ctypes.sizeof(ctypes.c_voidp) * 8), ".dll")))
<name-of-ghostscript-library-on-windows>

检查:函数的输出find_library不应为空。
如果输出为空,则可能是 Ghostscript 库不可用 // 变量之一,LD_LIBRARY_PATH具体DYLD_LIBRARY_PATH取决于PATH您的操作系统。在这种情况下,您可能必须修改其中一个路径变量。

三、安装 Camelot

1、pip
要使用 PyPI 从 PyPI 安装 Camelot pip,请包括cv如下所示的额外要求:

$ pip install "camelot-py[base]"

2、conda
conda是Anaconda发行版的包管理器和环境管理系统。它可用于从conda-forge频道安装 Camelot:

conda install -c conda-forge camelot-py

3、从源代码
安装依赖项后,您可以通过以下方式从源代码安装 Camelot:

a. 克隆 GitHub 存储库

$ git clone https://www.github.com/camelot-dev/camelot

b. 然后再次简单地使用 pip

$ cd camelot
$ pip install ".[base]"

四、初级使用

阅读 PDF 以使用 Camelot 提取表格非常简单。

首先导入 Camelot 模块:

import camelot

点击这里获取PDF文件

tables = camelot.read_pdf('foo.pdf')
tables

结果是

<TableList n=1>

现在,我们有一个TableList名为 的对象tables,它是一个Table对象列表。我们可以从这个对象中得到我们需要的一切。我们可以使用每个表的索引来访问它。从上面的代码片段中,我们可以看到该tables对象只有一个表,因为n=1. 让我们使用索引访问表0并查看它的shape.

tables[0]
<Table shape=(7, 7)>

让我们打印解析报告。

print tables[0].parsing_report

结果是

{
    'accuracy': 99.02,
    'whitespace': 12.24,
    'order': 1,
    'page': 1
}

准确性是一流的,并且空格较少,这意味着该表很可能被正确提取。table您可以使用对象的df属性以 pandas DataFrame 的形式访问该表。

tables[0].df

python中pdf标题提取 python pdf提取数据_字符串

您现在可以使用其to_csv()方法将表导出为 CSV 文件。to_json()或者,您可以使用或方法将表格分别导出为 JSON、Excel、HTML 文件或 sqlite 数据库。to_excel() to_html() to_markdown()to_sqlite()

tables[0].to_csv('foo.csv')

这会将表格导出为指定路径的 CSV 文件。在这种情况下,它foo.csv位于当前目录中。

tables您还可以使用对象的export()方法一次导出所有表。

tables.export('foo.csv', f='csv')

指定页码

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

camelot.read_pdf('your.pdf', pages='1,2,3')

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

阅读加密的 PDF

要从加密的 PDF 文件中提取表格,您必须在调用时提供密码read_pdf()。

tables = camelot.read_pdf('foo.pdf', password='******')
tables

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

将来可能会添加进一步的加密支持,但与此同时,如果您的 PDF 文件使用不受支持的加密算法,建议您在调用read_pdf(). 这可以通过QPDF等第三方工具成功实现。

qpdf --password=<PASSWORD> --decrypt input.pdf output.pdf

五、高级使用

资料来源PDF 在这里插入图片描述

python中pdf标题提取 python pdf提取数据_分隔符_02

处理背景线

要处理背景线,您可以通过process_background=True.

tables = camelot.read_pdf('background_lines.pdf', process_background=True)
tables[1].df

python中pdf标题提取 python pdf提取数据_CSV_03

可视化调试

您可以使用该plot()方法生成在处理 PDF 页面时检测到的各种元素的matplotlib图。这可以通过调整不同的配置参数来帮助您选择表格区域、列分隔符和调试错误的表格输出。

kind您可以使用关键字参数指定要绘制的元素类型。生成的图可以通过传递filename关键字参数保存到文件中。支持以下绘图类型:

文本
text
让我们绘制表格 PDF 页面上的所有文本。

camelot.plot(tables[0], kind='text').show()

网格

让我们绘制表格(看看它是否被正确检测到)。这种绘图类型以及等高线、直线和关节对于调试和改进提取输出很有用,以防表格未被正确检测到。(稍后会详细介绍。)

camelot.plot(tables[0], kind='grid').show()

python中pdf标题提取 python pdf提取数据_字符串_04

轮廓

contour
现在,让我们绘制表格 PDF 页面上存在的所有表格边界。

camelot.plot(tables[0], kind='contour').show()

python中pdf标题提取 python pdf提取数据_分隔符_05

线
line
可以绘制表格 PDF 页面上的所有线段。

camelot.plot(tables[0], kind='line').show()

联合的
joint
最后,让我们绘制表格 PDF 页面上存在的所有线交点。

camelot.plot(tables[0], kind='joint').show()

python中pdf标题提取 python pdf提取数据_分隔符_06

文本边缘
textedge

您还可以通过指定kind=‘textedge’. 要了解更多关于“textedge”是什么的信息,您可以查看Anssi Nurminen 硕士论文的第 20、35和 40 页。

camelot.plot(tables[0], kind='textedge').show()

python中pdf标题提取 python pdf提取数据_分隔符_07

指定表格区域

在这些情况下,指定准确的表边界会很有用。您可以在此页面上绘制文本并注意表格的左上角和右下角坐标。

您希望 Camelot 分析的表格区域可以作为逗号分隔的字符串列表传递给read_pdf(),使用table_areas关键字参数。

tables = camelot.read_pdf('table_areas.pdf', flavor='stream', table_areas=['316,499,566,337'])
tables[0].df

python中pdf标题提取 python pdf提取数据_字符串_08

指定列分隔符

指定列分隔符
在这种情况下,文本彼此非常接近,Camelot 可能会错误地猜测列分隔符的坐标。要更正此问题,您可以通过在页面上绘制文本来明确指定每个列分隔符的x坐标。read_pdf()您可以使用columns关键字参数将列分隔符作为逗号分隔的字符串列表传递给。如果您传递了单列分隔符字符串列表,并且未指定表格区域,则分隔符将应用于整个页面。当指定了表格区域列表并且您还需要指定列分隔符时,两个列表的长度应该相等。每个表格区域将使用它们的索引映射到每个列分隔符的字符串。
例如,如果您指定了两个表格区域,并且只想为第一个表格指定列分隔符,您可以像这样在列分隔符列表中为第二个表格传递一个空字符串,.table_areas=[‘12,54,43,23’, ‘20,67,55,33’]columns=[‘10,120,200,400’, ‘’]
绘制此PDF上存在的文本所得到的x坐标,然后将表格拿出来!

tables = camelot.read_pdf('column_separators.pdf', flavor='stream', columns=['72,95,209,327,442,529,566,606,683'])
tables[0].df

python中pdf标题提取 python pdf提取数据_分隔符_09

下期为大家分享介绍Camelot更多高级用法