from typing import List
from langchain.document_loaders.unstructured import UnstructuredFileLoader
from document_loaders.ocr import get_ocr
import tqdm
class RapidOCRPDFLoader(UnstructuredFileLoader):
def _get_elements(self) -> List:
def pdf2text(filepath):
import fitz # pyMuPDF里面的fitz包,不要与pip install fitz混淆
import numpy as np
ocr = get_ocr()
doc = fitz.open(filepath)
resp = ""
b_unit = tqdm.tqdm(total=doc.page_count, desc="RapidOCRPDFLoader context page index: 0")
for i, page in enumerate(doc):
# 更新描述
b_unit.set_description("RapidOCRPDFLoader context page index: {}".format(i))
# 立即显示进度条更新结果
b_unit.refresh()
# TODO: 依据文本与图片顺序调整处理方式
text = page.get_text("")
resp += text + "\n"
img_list = page.get_images()
for img in img_list:
pix = fitz.Pixmap(doc, img[0])
img_array = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.height, pix.width, -1)
result, _ = ocr(img_array)
if result:
ocr_result = [line[1] for line in result]
resp += "\n".join(ocr_result)
# 更新进度
b_unit.update(1)
return resp
text = pdf2text(self.file_path)
from unstructured.partition.text import partition_text
return partition_text(text=text, **self.unstructured_kwargs)
if __name__ == "__main__":
loader = RapidOCRPDFLoader(file_path="../tests/samples/ocr_test.pdf")
docs = loader.load()
print(docs)
from typing import TYPE_CHECKING
if TYPE_CHECKING:
try:
from rapidocr_paddle import RapidOCR
except ImportError:
from rapidocr_onnxruntime import RapidOCR
def get_ocr(use_cuda: bool = True) -> "RapidOCR":
try:
from rapidocr_paddle import RapidOCR
ocr = RapidOCR(det_use_cuda=use_cuda, cls_use_cuda=use_cuda, rec_use_cuda=use_cuda)
except ImportError:
from rapidocr_onnxruntime import RapidOCR
ocr = RapidOCR()
return ocr
from langchain.document_loaders.unstructured import UnstructuredFileLoader
from unstructured.partition.text import partition_text
这两行代码分别导入了两个关键模块:
UnstructuredFileLoader
(来自 langchain
)partition_text
(来自 unstructured
)它们通常用于加载非结构化文本文件并将其转换为可用于下游任务(如向量化、问答系统等)的格式。
UnstructuredFileLoader
UnstructuredFileLoader
是其提供的一个文档加载器类。将非结构化文本文件(如 .txt、.md、.csv 等)读取为 Document 对象。
Document 是 LangChain 中的一种标准数据结构,形式如下:
class Document:
page_content: str # 实际文本内容
metadata: dict # 元信息,如文件名、来源等
loader = UnstructuredFileLoader("example.txt")
documents = loader.load()
这会返回一个包含多个 Document
的列表,每个 Document
包含一页的内容和元信息。
partition_text
对纯文本进行语义级别的切分(例如按段落、句子等),便于后续处理。
它能识别出文本中的标题、段落、项目符号等内容,并以结构化方式返回。
from unstructured.partition.text import partition_text
elements = partition_text(filename="example.txt")
for element in elements:
print(element)
输出可能是:
Title: Introduction
NarrativeText: This is the first paragraph of the document.
ListItem: - First item
ListItem: - Second item
在实际应用中,你可以这样组合这两个模块:
from langchain.document_loaders.unstructured import UnstructuredFileLoader
from unstructured.partition.text import partition_text
# 自定义一个使用 partition_text 的 Loader
class CustomTextLoader(UnstructuredFileLoader):
def _get_elements(self):
return partition_text(filename=self.file_path)
# 使用自定义 Loader 加载文档
loader = CustomTextLoader("example.txt")
docs = loader.load()
这样做的好处是:
unstructured
强大的文本结构化解析能力
UnstructuredFileLoader
是 LangChain 中用于加载非结构化文件的标准工具,而partition_text
是底层unstructured
库中用于精细切分文本的方法,两者结合可以高效地将原始文本转化为结构化的文档对象,供 LLM 使用。
RapidOCRPDFLoader
这是一个自定义的 PDF 文档加载器类,继承自 LangChain 的 UnstructuredFileLoader
,用于读取 PDF 文件内容并将其转换为结构化文本格式,支持 OCR 图像识别。
from typing import List
from langchain.document_loaders.unstructured import UnstructuredFileLoader
from document_loaders.ocr import get_ocr
import tqdm
模块 | 功能 |
---|---|
List |
用于类型注解,表示返回的是一个列表 |
UnstructuredFileLoader |
LangChain 提供的基类,用于将文件转为 Document 对象 |
get_ocr |
自定义 OCR 工具函数(来自本地模块) |
tqdm |
显示进度条,提升用户体验 |
class RapidOCRPDFLoader(UnstructuredFileLoader):
def _get_elements(self) -> List:
UnstructuredFileLoader
_get_elements()
方法,这是所有 UnstructuredFileLoader
子类必须实现的方法。List
,包含从 PDF 中提取出的所有“元素”(如段落、标题等)pdf2text(filepath)
这个函数负责将 PDF 文件中的每一页转换为文本内容,并对图像执行 OCR 提取文字。
import fitz # PyMuPDF 的核心模块
import numpy as np
fitz
是 PyMuPDF 的核心模块,用于处理 PDF 和图像numpy
用于将图像像素数据转换为数组,便于 OCR 处理ocr = get_ocr()
get_ocr()
是你项目中封装的 OCR 函数,可能调用了 PaddleOCR、EasyOCR 或其它 OCR 引擎doc = fitz.open(filepath)
resp = ""
fitz.open()
打开 PDF 文件resp
用于拼接最终提取出的文本内容b_unit = tqdm.tqdm(total=doc.page_count, desc="RapidOCRPDFLoader context page index: 0")
for i, page in enumerate(doc):
b_unit.set_description("RapidOCRPDFLoader context page index: {}".format(i))
b_unit.refresh()
text = page.get_text("")
resp += text + "\n"
page.get_text("")
提取当前页的纯文本内容resp
字符串中img_list = page.get_images()
for img in img_list:
pix = fitz.Pixmap(doc, img[0])
img_array = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.height, pix.width, -1)
result, _ = ocr(img_array)
if result:
ocr_result = [line[1] for line in result]
resp += "\n".join(ocr_result)
page.get_images()
获取该页所有图像对象img_array
,以便输入给 OCRresp
中✅ 支持混合文本+图像的 PDF 内容提取
b_unit.update(1)
return resp
partition_text
结构化解析text = pdf2text(self.file_path)
from unstructured.partition.text import partition_text
return partition_text(text=text, **self.unstructured_kwargs)
unstructured
库提供的 partition_text
函数,对提取出的文本进行语义切分Title
NarrativeText
ListItem
这些结构化元素可以直接被 LangChain 的下游组件使用(如向量化、检索、QA Chain)
if __name__ == "__main__":
loader = RapidOCRPDFLoader(file_path="../tests/samples/ocr_test.pdf")
docs = loader.load()
print(docs)
Document
列表示例输出可能是:
[
Document(page_content='Introduction...', metadata={'source': 'ocr_test.pdf'}),
Document(page_content='Section 1:...', metadata={'source': 'ocr_test.pdf'}),
...
]
RapidOCRPDFLoader
是一个增强版的 PDF 加载器,它不仅能提取 PDF 中的文本,还能识别图像并执行 OCR,最后将内容结构化后返回,兼容 LangChain 的标准接口。