- 引言
- RAG数据简介
- PDF解析方法及工具
- 代码实现
- 总结
二、正文内容
- 引言
本文将介绍如何将RAG数据拆分至PDF格式,并探讨PDF解析的方法和工具,最后提供代码示例。
- RAG数据简介
RAG(关系型属性图)是一种用于表示实体及其关系的图数据结构。在RAG中,节点表示实体,边表示实体之间的关系,属性则用于描述实体和边的特征。
- PDF解析方法及工具
(1)PDF解析方法
- DOM解析:将PDF文档转换为树形结构,便于操作和遍历。
- SAX解析:基于事件驱动,适用于处理大型PDF文档。
(2)PDF解析工具
- PyPDF2:一个Python库,用于读取、分割、合并PDF文件。
- PDFMiner:一个强大的PDF解析库,支持提取文本、图片等元素。
- pdfplumber:一个专注于文本提取的PDF解析库。
- 代码实现
以下是一个使用PyPDF2将RAG数据拆分至PDF的示例代码:
import PyPDF2
# 读取PDF文件
with open('source.pdf', 'rb') as file:
reader = PyPDF2.PdfFileReader(file)
num_pages = reader.numPages
# 遍历每一页
for page_num in range(num_pages):
page = reader.getPage(page_num)
text = page.extractText()
# 拆分RAG数据
# 假设RAG数据以特定格式存储,例如:实体1-关系-实体2
entities = text.split('-')
# 创建新的PDF文件
pdf_writer = PyPDF2.PdfFileWriter()
pdf_writer.addPage(page)
with open(f'output/page_{page_num + 1}.pdf', 'wb') as output_file:
pdf_writer.write(output_file)
print('PDF文件拆分完成!')
解析表格:
def extract_continuous_tables(pdf, start_page_num):
"""
从指定页开始提取连续的表格内容
:param pdf: PDF文档对象
:param start_page_num: 开始页码
:return: 包含处理页码和表格文本的字典
"""
continuous_tables = [] # 存储连续表格内容
processed_pages = [] # 存储处理过的页码
current_page_num = start_page_num
# 添加起始页
processed_pages.append(current_page_num)
while current_page_num < len(pdf.pages):
current_page = pdf.pages[current_page_num]
current_page = remove_header_footer(current_page)
# 提取当前页的表格
current_tables = current_page.extract_tables()
if current_tables:
# 将当前页的表格添加到结果中
continuous_tables.extend(current_tables)
# 检查是否还有下一页
if current_page_num + 1 >= len(pdf.pages):
break
# 获取下一页内容
next_page = pdf.pages[current_page_num + 1]
next_page = remove_header_footer(next_page)
# 提取下一页的内容
next_page_tables = next_page.extract_tables()
next_page_words = next_page.extract_words(keep_blank_chars=True, extra_attrs=['fontname', 'size'])
# 过滤页眉页脚
header_height = 50
footer_height = 50
def is_header_content(word):
text = word['text'].lower()
# 位置检查
if word['top'] <= header_height or word['top'] >= (next_page.height - footer_height):
return True
# 电话号码模式
phone_patterns = [
r'tel[\s:]*[\d\-/]+',
r'电话[\s:]*[\d\-/]+',
r'传真[\s:]*[\d\-/]+',
r'fax[\s:]*[\d\-/]+',
r'\d{2,4}[\-/]\d{4,8}', # 匹配常见电话号码格式
]
# 使用正则表达式匹配
import re
if any(re.search(pattern, text, re.IGNORECASE) for pattern in phone_patterns):
return True
# 页眉特征检查
header_features = [
# 位置特征
word['top'] < header_height * 1.2, # 稍微放宽高度限制
word['size'] < 10, # 字体较小
# 内容特征
any(pattern in text for pattern in [
'页码', '第', '页', 'page',
'copyright', '版权所有',
'机密', '保密',
'草稿', 'draft',
'文档编号', 'doc',
'日期', 'date'
]),
# 格式特征
bool(re.match(r'.*\d+.*页', text)), # 包含页码
bool(re.match(r'.*\d{4}[-/]\d{1,2}[-/]\d{1,2}', text)), # 日期格式
]
return any(header_features)
# 过滤词
filtered_words = [
word for word in next_page_words
if not is_header_content(word)
]
# 如果需要,还可以按垂直位置排序
filtered_words.sort(key=lambda x: x['top'])
# 判断下一页是否以表格开始
starts_with_table = False
if filtered_words and next_page_tables: # 确保有文字和表格
try:
if next_page_tables[0] and next_page_tables[0][0]: # 确保表格有内容
# 获取第一个表格的位置
first_table = next_page.find_tables()[0]
if first_table:
first_table_top = first_table.bbox[1]
# 获取第一个文字的位置
first_word_top = filtered_words[0]['top']
# 如果表格在文字之前,则认为页面以表格开始
if first_table_top < first_word_top:
starts_with_table = True
except (IndexError, AttributeError):
starts_with_table = False
if not starts_with_table:
# 如果下一页不是以表格开始,则结束提取
break
# 继续处理下一页
current_page_num += 1
processed_pages.append(current_page_num)
# 将表格转换为文本
table_texts = []
for table in continuous_tables:
if table:
table_text = []
for row in table:
# 过滤None和空字符串,并确保所有值都转换为字符串
row_text = []
for cell in row:
if cell is not None and str(cell).strip():
cell_str = str(cell).strip().replace("\n", " ")
# if cell_str: # 只添加非空字符串
row_text.append(cell_str)
else:
row_text.append(" ") # 将None转换为空字符串
if row_text: # 只添加非空行
table_text.append('##'.join(row_text))
filtered_table_text = [row for row in table_text if '##' in row]
if filtered_table_text:
table_texts.append('\n'.join(filtered_table_text))
# 返回包含页码列表和表格文本的字典
result = {
'processed_pages': processed_pages,
'table_text': '\n\n'.join(table_texts) if table_texts else ""
}
return result
1.pdfplumber
https://blog.****.net/fuhanghang/article/details/122579548
1
pdfplumber的主要类和方法
pdfplumber对于表格的提取
参考https://github.com/jsvine/pdfplumber/blob/stable/examples/notebooks/extract-table-ca-warn-report.ipynb
1
代码:
pdf = pdfplumber.open("../pdfs/ca-warn-report.pdf")
p0=pdf.pages[0]
im = p0.to_image() #display 第一页
table = p0.extract_table() 抽取其中最大的表格
import pandas as pd
df = pd.DataFrame(table[1:], columns=table[0])
for column in ["Effective", "Received"]:
df[column] = df[column].str.replace(" ", "") 使用panda来吧table抽取到的数据转成dataFrame格式
- 总结
本文介绍了RAG数据拆分至PDF的方法和工具,并通过代码示例展示了如何使用PyPDF2进行PDF文件拆分。在实际应用中,可根据需求选择合适的解析方法和工具。
希望这个分享笔记大纲和代码示例能帮助你完成你的分享笔记。在实际编写过程中,可以根据具体需求进行调整和优化。