如何使用 Python 从发票中提取数据:分步指南

如何使用 Python 从发票中提取数据:分步指南

源节点: 2049768

在当今快节奏的商业环境中,处理发票和付款是各种规模的公司的一项重要任务。

发票包含重要信息,例如客户和供应商详细信息、订单信息、定价、税金和付款条件。

手动管理发票数据提取可能既复杂又耗时,尤其是对于大量发票。

例如,企业可能会收到各种格式的发票,例如纸质、电子邮件、PDF 或电子数据交换 (EDI)。 此外,发票可能包含结构化数据(例如表格)以及非结构化数据(例如自由文本描述、徽标和图像)。

手动提取和处理此信息可能容易出错,从而导致延迟、不准确和错失机会。

幸运的是,Python 提供了一组强大而灵活的工具来自动提取和处理发票数据。

在本分步指南中,我们将探索如何利用 Python 从发票中提取结构化和非结构化数据、处理 PDF 以及与机器学习模型集成。

阅读本指南后,您将深入了解如何使用 Python 从发票数据中提取有价值的见解,这可以帮助您简化业务流程、优化现金流并在您的行业中获得竞争优势。 让我们开始吧。

首先,让我们了解什么是发票!

发票是概述买卖双方交易细节的文件,包括交易日期、买卖双方的名称和地址、对提供的商品或服务的描述、物品的数量、每单位的价格,以及应付的总额。

尽管发票看似简单,但从中提取数据可能是一个复杂且具有挑战性的过程。 这是因为发票可能同时包含结构化和非结构化数据。

结构化数据是指以特定格式组织的数据,例如表格或列表。 发票通常包含表格形式的结构化数据,这些数据概述了所提供的商品或服务的项目和数量。

另一方面,非结构化数据是指未以特定格式组织的数据,可能更难识别和提取。 发票可能包含自由文本描述、徽标或图像形式的非结构化数据。

从发票中提取数据可能代价高昂,并可能导致付款处理延迟,尤其是在处理大量发票时。 这就是发票数据提取的用武之地。

发票数据提取是指从发票中提取结构化和非结构化数据的过程。 由于发票数据类型多种多样,此过程可能具有挑战性,但可以使用 Python 等工具自动执行。

如前所述,并非每张发票都易于提取,因为它们有不同的形式和模板。 以下是企业在从发票中提取数据时面临的一些挑战:

  • 多种发票格式:发票可能采用不同的格式,包括纸质、电子邮件、PDF 或电子数据交换 (EDI),这可能导致难以一致地提取和处理数据。
  • 数据质量和准确性:手动处理发票容易出错,导致付款处理延迟和不准确。
  • 海量数据:许多企业处理大量发票,手动处理这些发票既困难又耗时。
  • 不同的语言和字体大小:来自国际供应商的发票可能使用不同的语言,使用自动化工具可能难以处理。 同样,发票可能包含不同的字体大小和样式,这会影响数据提取的准确性。
  • 与其他系统集成:从发票中提取的数据通常需要与其他系统集成,例如会计或企业资源规划 (ERP) 软件,这会给流程增加一层额外的复杂性。

Python 是一种流行的编程语言,用于广泛的数据提取和处理任务,包括从发票中提取数据。 它的多功能性使其成为技术领域的强大工具——从构建机器学习模型和 API 到自动化发票提取流程。

让我们通过示例简要了解可用于发票提取的 Python 库:

金字塔

Pytesseract 是 Google 的 Tesseract OCR 引擎的 Python 包装器,它是最流行的 OCR 引擎之一。 Pytesseract 旨在从扫描图像(包括发票)中提取文本,并可用于从发票的页眉和页脚部分提取键值对和其他文本信息。

Textract 是一个 Python 库,可以从各种文件格式(包括 PDF、图像和扫描文档)中提取文本和数据。 Textract 使用 OCR 和其他技术从这些文件中提取文本和数据,并可用于从发票的所有部分中提取文本和数据。

熊猫

Pandas 是一个强大的 Python 数据操作库,它提供了用于高效存储和操作大型数据集的数据结构。 Pandas 可用于从发票的行项目部分提取和操作表格数据,包括产品描述、数量和价格。

塔布拉

Tabula 是一个 Python 库,专门设计用于从 PDF 和其他文档中提取表格数据。 Tabula 可用于从发票的行项目部分提取数据,包括产品描述、数量和价格,并且可以作为基于 OCR 方法提取此数据的有用替代方法。

柯莱特

Camelot 是另一个 Python 库,可用于从 PDF 和其他文档中提取表格数据,专门用于处理复杂的表格结构。 Camelot 可用于从发票的行项目部分提取数据,并且可以作为基于 OCR 方法提取此数据的有用替代方法。

OpenCV的

OpenCV 是一个流行的 Python 计算机视觉库,它提供了用于分析和处理图像的工具和技术。 OpenCV 可用于从发票页眉和页脚部分的图像和徽标中提取信息,并可与基于 OCR 的方法结合使用以提高准确性和可靠性。

枕头

Pillow 是一个 Python 库,它提供用于处理图像的工具和技术,包括读取、写入和操作图像文件。 Pillow 可用于从发票页眉和页脚部分的图像和徽标中提取信息,并可与基于 OCR 的方法结合使用以提高准确性和可靠性。

需要注意的是,虽然上面提到的库是一些最常用于从发票中提取数据的库,但从发票中提取数据的过程可能很复杂,可能需要多种技术和工具。

根据发票的复杂程度和您需要提取的具体信息,您可能需要使用此处未提及的其他库和技术。

现在,在深入研究提取发票的真实示例之前,让我们首先讨论准备提取发票数据的过程。

在提取之前准备数据是发票处理管道中的重要步骤,因为它可以帮助确保数据准确可靠。 在处理大量数据或处理可能包含错误、不一致或其他可能影响提取过程准确性的问题的非结构化数据时,这一点尤为重要。

准备要提取的发票数据的一项关键技术是数据清理和预处理。

数据清理和预处理涉及在提取过程开始之前识别和纠正数据中的错误、不一致和其他问题。 这可能涉及多种技术,包括:

  • 数据规范化:将数据转换为更易于处理和分析的通用格式。 这可能涉及标准化日期、时间和其他数据元素的格式,以及将数据转换为一致的数据类型,例如数字或分类数据。
  • 文字清洗:涉及从数据中删除无关或不相关的信息,例如停用词、标点符号和其他非文本字符。 这有助于提高基于文本的提取技术(例如 OCR 和 NLP)的准确性和可靠性。
  • 数据验证:涉及检查数据是否存在错误、不一致和其他可能影响提取过程准确性的问题。 这可能涉及将数据与外部来源(例如客户数据库或产品目录)进行比较,以确保数据准确且最新。
  • 资料扩充:添加或修改数据以提高提取过程的准确性和可靠性。 这可能涉及添加额外的数据源,例如社交媒体或网络数据,以补充发票数据,或使用机器学习技术生成合成数据以提高提取过程的准确性。

从发票中提取数据是一项复杂的任务,需要结合使用技术和工具。 使用单一技术或库通常是不够的,因为每张发票都不同,而且它们的布局和格式可能有很大差异。 但是,如果您可以访问一组电子生成的发票,则可以使用各种技术(例如正则表达式匹配和表格提取)从中提取数据。

例如,要从 PDF 发票中提取表格,您可以使用从 PDF 中的表格中提取数据的 tabula-py 库。 通过提供表格所在的 PDF 页面区域,您可以提取表格并使用 pandas 库对其进行操作。

另一方面,非电子发票,例如扫描发票或基于图像的发票,需要更先进的技术,包括计算机视觉和机器学习。 这些技术可以智能识别发票区域并提取数据。

使用机器学习提取发票的优势之一是算法可以从训练数据中学习。 一旦算法经过训练,它就可以智能识别新发票,而无需重新训练算法。 这意味着该算法可以根据以前的输入快速准确地从新发票中提取数据。

在本节中,让我们使用正则表达式从发票中提取几个字段。

第 1 步:导入库

为了从发票文本中提取信息,我们使用正则表达式和 pdftotext 库从 PDF 发票中读取数据。

import pdftotext
import re

第 2 步:阅读 PDF

我们首先使用 Python 的内置读取 PDF 发票 open() 功能。 'rb' 参数以二进制模式打开文件,这是读取 PDF 等二进制文件所必需的。 然后我们使用 pdftotext 库从 PDF 文件中提取文本内容。

with open('invoice.pdf', 'rb') as f:
pdf = pdftotext.PDF(f)
text = 'nn'.join(pdf)

第三步:使用正则表达式匹配发票上的文字

我们使用正则表达式从发票文本中提取发票号、到期总金额、发票日期和到期日。 我们使用 re.compile() 功能和使用 search() 函数查找文本中模式的第一次出现。 我们使用 group() 函数从模式中提取匹配的文本,以及 strip() 函数从匹配的文本中删除任何前导或尾随空格。 如果未找到匹配项,我们将相应的值设置为 None。

invoice_number = re.search(r'Invoice Numbers*ns*n(.+?)s*n', text).group(1).strip()
total_amount_due = re.search(r'Total Dues*ns*n(.+?)s*n', text).group(1).strip() # Extract the invoice date
invoice_date_pattern = re.compile(r'Invoice Dates*ns*n(.+?)s*n')
invoice_date_match = invoice_date_pattern.search(text)
if invoice_date_match: invoice_date = invoice_date_match.group(1).strip()
else: invoice_date = None # Extract the due date
due_date_pattern = re.compile(r'Due Dates*ns*n(.+?)s*n')
due_date_match = due_date_pattern.search(text)
if due_date_match: due_date = due_date_match.group(1).strip()
else: due_date = None

第 4 步:打印数据

最后,我们打印从发票中提取的所有数据。

print('Invoice Number:', invoice_number)
print('Date:', date)
print('Total Amount Due:', total_amount_due)
print('Invoice Date:', invoice_date)
print('Due Date:', due_date)

输入

样品发票.pdf

输出

Invoice Date: January 25, 2016
Due Date: January 31, 2016
Invoice Number: INV-3337
Date: January 25, 2016
Total Amount Due: $93.50

请注意,此处描述的方法特定于示例发票的结构和格式。 在实践中,从不同发票中提取的文本可能具有不同的形式和结构,因此很难应用一刀切的解决方案。 要处理此类变化,可能需要高级技术,例如命名实体识别 (NER) 或键值对提取,具体取决于具体用例。

从电子生成的 PDF 发票中提取表格可能是一项简单的任务,这要归功于 Tabula 和 Camelot 等图书馆。 以下代码演示了如何使用这些库从 PDF 发票中提取表格。

from tabula import read_pdf
from tabulate import tabulate
file = "sample-invoice.pdf"
df = read_pdf(file ,pages="all")
print(tabulate(df[0]))
print(tabulate(df[1]))

输入

样品发票.pdf

输出

- ------------ ----------------
0 Order Number 12345
1 Invoice Date January 25, 2016
2 Due Date January 31, 2016
3 Total Due $93.50
- ------------ ---------------- - - ------------------------------- ------ ----- ------
0 1 Web Design $85.00 0.00% $85.00 This is a sample description...
- - ------------------------------- ------ ----- ------

如果您需要从发票(非结构化发票)中提取特定列,并且发票包含多个格式不同的表格,您可能需要执行一些后处理以获得所需的输出。 然而,为了应对这些挑战,可以使用计算机视觉和光学字符识别 (OCR) 等先进技术从发票中提取数据,而不管发票的布局如何。

识别发票布局以应用 OCR

在此示例中,我们将使用 Tesseract(一种流行的 Python OCR 引擎)来解析发票图像。

第一步:导入必要的库

首先,我们导入必要的库:用于图像处理的 OpenCV (cv2) 和用于 OCR 的 pytesseract。 我们还从 pytesseract 导入 Output 类来指定 OCR 结果的输出格式。

import cv2
import pytesseract
from pytesseract import Output

第 2 步:阅读示例发票图像

然后我们使用读取示例发票图像 sample-invoice.jpg cv2.imread() 并将其存储在 img 变量中。

img = cv2.imread('sample-invoice.jpg')

第三步:对图片进行OCR,得到字典格式的结果

接下来,我们使用 pytesseract.image_to_data() 对图像执行 OCR 并获得有关检测到的文本的信息字典。 这 output_type=Output.DICT 参数指定我们想要字典格式的结果。

然后,我们使用 keys() 函数打印生成的字典的键,以查看我们可以从 OCR 结果中提取的可用信息。

d = pytesseract.image_to_data(img, output_type=Output.DICT)
# Print the keys of the resulting dictionary to see the available information
print(d.keys())

第 4 步:通过绘制边界框可视化检测到的文本

为了可视化检测到的文本,我们可以使用字典中的信息绘制每个检测到的单词的边界框。 我们首先使用 len() 函数,然后遍历每个块。 对于每个块,我们检查检测到的文本的置信度分数是否大于 60(即,检测到的文本更有可能是正确的),如果是,我们检索边界框信息并使用以下命令在文本周围绘制一个矩形 cv2.rectangle(). 然后我们使用显示结果图像 cv2.imshow() 并在关闭窗口之前等待用户按下一个键。

n_boxes = len(d['text'])
for i in range(n_boxes): if float(d['conf'][i]) > 60: # Check if confidence score is greater than 60 (x, y, w, h) = (d['left'][i], d['top'][i], d['width'][i], d['height'][i]) img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.imshow('img', img)
cv2.waitKey(0)

输出

命名实体识别 (NER) 是一种自然语言处理技术,可用于从非结构化文本中提取结构化信息。 在发票提取的上下文中,NER 可用于识别关键实体,例如发票编号、日期和金额。

用于发票信息提取的NER模型

一个包含 NER 功能的流行 NLP 库是 空间. spaCy 以多种语言(包括英语)为 NER 提供预训练模型。 以下是如何使用 spaCy 从发票中提取信息的示例:

第 1 步:导入 Spacy 并加载预训练模型

在这个例子中,我们首先使用 NER 加载预训练英语模型 spacy.load() 功能。

import spacy
# Load the English pre-trained model with NER
nlp = spacy.load('en_core_web_sm')

第 2 步:将 PDF 发票作为字符串读取并将 NER 模型应用于发票文本

然后,我们将发票 PDF 文件作为字符串读取,并使用 NER 模型将 NER 模型应用于文本 nlp() 功能。

with open('invoice.pdf', 'r') as f: text = f.read() # Apply the NER model to the invoice text
doc = nlp(text)

第 3 步:提取发票编号、日期和到期总金额

然后,我们使用 for 循环遍历发票文本中检测到的实体。 我们使用 label_ attribute 每个实体,以检查它是否与发票编号、日期或应付总额相符。 我们使用字符串匹配和小写来​​根据上下文线索识别这些实体。

invoice_number = None
invoice_date = None
total_amount_due = None for ent in doc.ents: if ent.label_ == 'INVOICE_NUMBER': invoice_number = ent.text.strip() elif ent.label_ == 'DATE': if ent.text.strip().lower().startswith('invoice'): invoice_date = ent.text.strip() elif ent.label_ == 'MONEY': if 'total' in ent.text.strip().lower(): total_amount_due = ent.text.strip()

第四步:打印提取的信息
最后,我们将提取的信息打印到控制台进行验证。 请注意,NER 模型的性能可能会因输入数据的质量和可变性而异,因此可能需要进行一些手动调整以提高提取信息的准确性。

print('Invoice Number:', invoice_number)
print('Invoice Date:', invoice_date)
print('Total Amount Due:', total_amount_due)

在下一节中,我们将讨论自动发票提取的一些常见挑战和解决方案。

常见挑战和解决方案

尽管使用 Python 提取发票数据有很多好处,但企业在此过程中仍可能面临挑战。 以下是发票数据提取过程中出现的一些常见挑战以及克服这些挑战的可能解决方案:

格式不一致

发票可以采用多种格式,包括纸质、PDF 和电子邮件,这使得一致地提取和处理数据变得具有挑战性。 此外,发票的结构可能并不总是相同的,这可能会导致数据提取出现问题

扫描质量差

低质量扫描或倾斜角度扫描会导致数据提取错误。 为了提高数据提取的准确性,企业可以使用去偏移、二值化和降噪等图像预处理技术来提高扫描质量。

不同的语言和字体大小

来自国际供应商的发票可能使用不同的语言,这可能难以使用自动化工具进行处理。 同样,发票可能包含不同的字体大小和样式,这会影响数据提取的准确性。 为了克服这一挑战,企业可以使用光学字符识别 (OCR) 等机器学习算法和技术来准确提取数据,而无需考虑语言或字体大小。

复杂的发票结构

发票可能包含复杂的结构,例如嵌套表格或混合数据类型,这些结构可能难以提取和处理。 为了克服这一挑战,企业可以使用 Pandas 等库来处理复杂的结构并准确地提取数据。

与其他系统 (ERP) 集成

从发票中提取的数据通常需要与其他系统集成,例如会计或企业资源规划 (ERP) 软件,这会给流程增加一层额外的复杂性。 为了克服这一挑战,企业可以使用 API 或数据库连接器将提取的数据与其他系统集成。

通过了解并克服这些常见挑战,企业可以更高效、更准确地从发票中提取数据,并获得有助于优化业务流程的宝贵见解。

借助 Nanonets,您可以使用基于 Web 的直观 GUI 轻松创建和训练用于发票数据提取的机器学习模型。 您可以访问使用最先进算法为您提供准确结果的云托管模型,而无需担心获取 GCP 实例或 GPU 进行训练。

使用 Nanonets,您将获得

易于使用的基于 Web 的 GUI
Nanonets 提供了一个直观的基于 Web 的 GUI,该 GUI 可以与我们的 API 进行通信,允许您创建模型、根据您的数据对其进行训练、获取精度和准确度等基本指标,并对您的图像进行推理,所有这些都无需编写任何代码。

云托管模型: 借助 Nanonets,您可以访问多个开箱即用的模型来获得解决方案。 或者,您可以构建托管在云上的模型,并且可以通过 API 请求访问以进行推理。 无需担心获取 GCP 实例或 GPU 进行训练。

最先进的算法: Nanonets 的模型使用最先进的算法为您提供最佳结果。 这些模型不断发展,以通过更多更好的数据、更好的技术、更好的架构设计和更强大的超参数设置变得更加有效。

字段提取变得容易: 构建发票数字化产品的最大挑战是为提取的文本提供结构。 Nanonets 的 OCR API 自动提取所有必要的字段和值,并将它们放在表格或 JSON 格式中,以便您轻松访问和构建。

自动化驱动: 在 Nanonets,我们相信自动化的力量。 我们努力让机器学习无处不在,我们的目标是让您解决的任何业务问题在未来都需要最少的人工监督和预算。 发票数字化等流程的自动化可以在货币收益、客户满意度和员工满意度方面对您的组织产生巨大影响。

开始使用 Nanonets 数字化发票——一键数字化:

总结

发票数据提取对于处理大量发票的企业来说是一个关键过程。 从发票中准确提取数据可以显着减少错误、简化付款处理并最终提高您的底线。

Python 是一个强大的工具,可以简化和自动化发票数据提取过程。 它的多功能性和众多库使其成为希望提高发票数据提取能力的企业的理想选择。

此外,借助 Nanonets,您可以进一步简化发票数据提取过程。 我们易于使用的平台提供了一系列功能,包括直观的基于 Web 的 GUI、云托管模型、最先进的算法和简单的字段提取。

因此,如果您正在寻找一种高效且具有成本效益的发票数据提取解决方案,Nanonets 是您的不二之选。 立即注册我们的服务并开始优化您的业务流程!

时间戳记:

更多来自 人工智能与机器学习