ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: normal;text-wrap: wrap;">本文主要介绍了四种处理 PDF 文件的工具,分别是 PyPDF、Camelot、Tabula 和 Adobe PDF Services API,用于提取 PDF 文件中的文本、表格和图像。 ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: normal;text-wrap: wrap;">大量信息来源于文本数据,例如PDF文档。处理PDF可能特别具有挑战性,尤其是在处理表格和图像时。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: normal;text-wrap: wrap;">如果您使用单模态语言模型,那么您可能已经知道它不具备直接解释或“读取”文档的能力。它只能处理一种类型的输入,例如纯文本或纯图像。如果您需要分析PDF中的图像或图表以用于下游任务,例如问答,您通常会使用专门的软件包来解析文档。这些工具可以将文档、文档中找到的图像和表格转换为模型可以理解和分析的文本格式。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: normal;text-wrap: wrap;">有几种优秀的工具可用于解析PDF文档以用于下游任务。在本文中,我们将介绍一些优秀的工具,包括PyPDF、Adobe PDF Services API、Camelot和Tabula。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: normal;text-wrap: wrap;">首先,让我们安装相关的库:!pip install pdfservices-sdk !pip install openpyxl !pip install camelot-py !pip install opencv-python !pip install tabula-py==2.9.0 !pip install jpype1 !pip install langchain !pip install langchain-core==0.1.40
ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: normal;text-wrap: wrap;">使用PyPDF提取文本、表格和图像ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: normal;text-wrap: wrap;">Pypdf是一个用途广泛且常用的库,用于解析PDF文档。它可以解析文档,包括文档中的表格,并将其转换为文本。大多数情况下,使用PyPDF解析文档时,表格的格式也能得到很好的保留。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: normal;text-wrap: wrap;text-align: center;"> ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: normal;text-wrap: wrap;text-align: center;">图片由作者提供ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: normal;text-wrap: wrap;">Langchain document_loaders 集成了许多不同的软件包,用于读取各种文件格式,包括PyPDF。以下脚本使用PyPDF处理文档并将其保存为数据框格式:from langchain_community.document_loaders import PyPDFLoader
def extract_text_from_file(df, file_path): file_name = file_path.split("/")[-1] file_type = file_name.split(".")[-1] if file_type == "pdf": loader = PyPDFLoader(file_path) else: return df
text = "" pages = loader.load_and_split() for page in pages: text += page.page_content # Create a new df and concatenate new_row = pd.DataFrame({"file": [file_name], "text": [text]}) df = pd.concat([df, new_row], ignore_index=True)
return df
#Apply the function: folder_path = '../data/raw' pathlist = Path(folder_path).glob('*.pdf') filenames = [] for file_path in pathlist: filename = os.path.basename(file_path) filenames.append(filename)
df = pd.DataFrame() for filename in filenames: file_path = folder_path + "/" + filename file_name = os.path.basename(file_path) print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} process {file_name}") # Initialize an empty df df_file = pd.DataFrame(columns=["file", "text"]) print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} extract text") try: df_file = extract_text_from_file(df_file, file_path) except Exception as e: print("----Error: cannot extract text") print(f"----error: {e}") df = pd.concat([df, df_file])
df

您还可以单独处理每一页,例如,如果您想对每个块/页执行下游问答任务。在这种情况下,您可以修改脚本,如下所示: def extract_text_from_file(df, file_path): file_name = file_path.split("/")[-1] file_type = file_name.split(".")[-1] if file_type == "pdf": loader = PyPDFLoader(file_path) elif file_type == "docx": loader = Docx2txtLoader(file_path) else: return df
pages = loader.load_and_split() for page_number, page in enumerate(pages, start=1): # Each page's text is added as a new row in the DataFrame new_row = pd.DataFrame({ "file": [file_name], "page_number": [page_number], "text": [page.page_content] }) df = pd.concat([df, new_row], ignore_index=True)
return df

PDF文档的每一页都可以包含任意数量的图像。您是否知道您也可以使用PyPDF从文档中提取所有图像? 以下代码块从pdf文件中提取所有图像,并创建一个新文件夹来存储提取的图像: from pypdf import PdfReader import os output_directory = '../data/processed/images/image_pypdf' if not os.path.exists(output_directory): os.mkdir(output_directory) reader = PdfReader("../data/raw/GPTsareGPTs.pdf") for page in reader.pages: for image in page.images: with open(os.path.join(ouput_directory,image.name), "wb") as fp: fp.write(image.data)
在文件夹中,您将找到PDF中的所有图像: PyPDF提取的PDF中所有图像的列表。图片由作者提供
使用Adobe PDF Services API提取文本、表格和图像PDF Extract API(包含在PDF Services API中)提供了基于云的功能,用于自动从PDF中提取内容。 PDF Services API 需要一个 access_token 来授权请求。为了使用访问令牌,您需要创建一个。当您收到包含 json 格式的 'client_id' 和 'client_secret' 的开发者凭据后,就可以使用它来处理您的 PDF。让我们首先导入相关的库: ```python from adobe.pdfservices.operation.auth.credentials import Credentials from adobe.pdfservices.operation.exception.exceptions import ServiceApiException, ServiceUsageException, SdkException from adobe.pdfservices.operation.execution_context import ExecutionContext from adobe.pdfservices.operation.io.file_ref import FileRef from adobe.pdfservices.operation.pdfops.extract_pdf_operation import ExtractPDFOperation from adobe.pdfservices.operation.pdfops.options.extractpdf.extract_pdf_options import ExtractPDFOptions from adobe.pdfservices.operation.pdfops.options.extractpdf.extract_element_type import ExtractElementType from adobe.pdfservices.operation.pdfops.options.extractpdf.extract_renditions_element_type import \ ExtractRenditionsElementType import os.path import zipfile import json import pandas as pd import re import openpyxl from datetime import datetime ```
以下脚本使用必要的凭据设置 Adobe PDF Services API,处理 PDF 文件并将结果保存在 zip 文件中: ```python def adobeLoader(input_pdf, output_zip_path,client_id, client_secret): """ 运行 adobe API 并创建输出 zip 文件的函数 """ # 初始化设置,创建凭据实例。 credentials = Credentials.service_principal_credentials_builder() \ .with_client_id(client_id) \ .with_client_secret(client_secret) \ .build()
# 使用凭据创建 ExecutionContext 并创建一个新的操作实例。 execution_context = ExecutionContext.create(credentials) extract_pdf_operation = ExtractPDFOperation.create_new()
# 从源文件设置操作输入。 source = FileRef.create_from_local_file(input_pdf) extract_pdf_operation.set_input(source)
# 构建 ExtractPDF 选项并将其设置到操作中 extract_pdf_options: ExtractPDFOptions = ExtractPDFOptions.builder() \ .with_elements_to_extract([ExtractElementType.TEXT, ExtractElementType.TABLES]) \ .with_elements_to_extract_renditions([ExtractRenditionsElementType.TABLES, ExtractRenditionsElementType.FIGURES]) \ .build() extract_pdf_operation.set_options(extract_pdf_options)
# 执行操作。 result: FileRef = extract_pdf_operation.execute(execution_context)
# 将结果保存到输出路径 if os.path.exists(output_zip_path): os.remove(output_zip_path) result.save_as(output_zip_path) ```
此 'adobeLoader' 操作的输出是一个 'sdk.zip' 包,其中包含以下内容: 'structuredData.json' 文件 文本存储在 json 文件中,并按上下文块提取——段落、标题、列表、脚注。 “table”文件夹:表格被提取并解析,并为每个单元格提供内容和表格格式信息。表格数据在生成的 JSON 中提供,也可以选择以 CSV 和 XLSX 文件输出。表格也输出为 PNG 图像,以便可以直观地验证表格数据。 “figures”文件夹:被识别为图形或图像的对象将提取为 PNG 文件。

输出文件夹结构 现在,您可以将该函数应用于您的文档: ```python # Adobe 输出 zip 文件路径 input_pdf = 'data/raw/GPTsareGPTs.pdf' output_zip_path = 'data/processed/adobe_result/sdk.zip' output_zipextract_folder = 'data/processed/adobe_result/' # 运行 adobe API adobeLoader(input_pdf, output_zip_path) ```
您可以看到“figures”文件夹以 .png 格式返回我的 PDF 文档中的所有图像。表格文件夹返回表格的 Excel 工作表,这确保了高保真度和准确性,以及用于视觉比较目的的 .png 图像。 您还可以进一步处理结构化 JSON 文件structuredData.json以收集文本和表格,并将这些数据组织到 pandas DataFrame 中,以用于进一步的下游任务: 
使用 Camelot 和 Tabular 提取表格Tabula 和 Camelot 是两个专门为从 PDF 中提取表格而设计的 Python 库。 以下脚本使用 Tabula 或 Camelot 处理 PDF 文档,将文档中的每个表格转换为 JSON 格式,同时捕获实际表格数据和元数据(例如表格编号和页码): ```python def extract_tables(file_path, pages="all", package="tabula"): if package == "camelot": # 使用 camelot 提取表格 # flavor 可以是 'stream' 或 'lattice',对于表格没有清晰边框的文档,stream flavor 通常更合适。 tables = camelot.read_pdf(file_path, pages=pages, flavor="stream") else: tables = tabula.read_pdf(file_path, pages=pages, stream=True, silent=True)
# 将表格转换为 JSON tables_json = [] for idx, table in enumerate(tables):
if package == "camelot": page_number = table.parsing_report["page"] data = table.df.to_json(orient="records") else: page_number = "" data = table.to_json(orient="records")
data = { "table_number": idx, "page_number": page_number, "data": data, } tables_json.append(data) return tables_json ```
太棒了!现在我们有了处理表格的脚本,我们可以将该函数应用于相同的 Pdf 文档: file_path = '../data/raw/GPTsareGPTs.pdf' file_name = os.path.basename(file_path) df_file = pd.DataFrame() print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} process {file_name}")
print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} extract table")
all_tables = [] for package in ["camelot", "tabula"]: print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} extract table with {package}") try: tables_from_package = extract_tables(file_path, pages="all", package=package) # list of json for table in tables_from_package: all_tables.append({"table": table, "source": package}) except Exception as e: print("----Error: cannot extract table") print(f"----error: {e}")
# Now you can access each table along with its source for entry in all_tables: print(f"Source: {entry['source']}, Table: {entry['table']}")
下面是源 PDF 文档中的一个表格示例: 
Camelot 或 Tabula 操作的输出格式实际上是表格的字符串表示形式,如下面的 json 对象所示: Tabula 的输出
当您切片 json 对象中的['data']键时,VS Code 似乎理解它是一种表格格式,并显示字符串的表格表示形式,这看起来与 PDF 文件中源表格中的完全相同。Tabula 似乎正确检测到了表格。棒极了! Tabula 的输出
现在,让我们看一下 Camelot 的输出。以下显示了同一个表格的 json 对象。 Camelot 的输出
以及字符串的表格表示: Camelot 的输出。Camelot 未能检测到表格的边界。当文本离表格太近时,它会包含文本。
在这个例子中,Tabula 和 Camelot 都能够检测到表格,但是 Tabular 的输出很干净,并且镜像了 PDF 中的原始表格。同时,Camelot 似乎未能检测到表格的边界。当文本离表格太近时,它会包含文本。 但是,在另一个例子中,当一个页面上有多个表格,并且没有像下面这样清晰的表格边界时: 
Camelot 成功检测到两个表格,而 Tabula 未能检测到任何一个表格: Camelot 的输出 Camelot 的输出
不同工具的比较在考虑选择哪种选项来解析 PDF 文档时,PyPDF 是基本提取需求的理想选择,在这些需求中,表格结构可能不是优先事项。它是完全免费的,适合预算紧张且需要简单解决方案以高精度提取文本和图像的用户。根据我的经验,大多数情况下,将表格格式保留为文本是可以接受的。 Camelot 和 Tabula 专为表格提取而设计,最适合需要提取表格数据的场景。它们也是完全免费的,在我看来,如果您对偶尔的不准确性没有意见,那么它们就足够好了。 Adobe PDF Services API 为企业或应用程序提供了一个非常强大的解决方案,在这些企业或应用程序中,文本、表格和图像提取的高精度至关重要。但是,没有关于 API 定价的明确信息。这里说您需要联系销售人员获取报价。在这个主题上,Adobe Extract API 似乎相当昂贵。实际上,我** **愿意为实际使用付费,因为提取的输出质量是优质的! 
结论在本文中,我们学习了四种不同的工具来解析 PDF 文档并从 PDF 文件中提取文本、表格和图像数据:PyPDF、Camelot、Tabula 和 Adobe PDF Services API。 感谢您的阅读。我希望它对您有效地将 PDF 内容转换为结构化和可操作的数据有所帮助。 |