RAG数据拆分之PDF

  1. 引言
  2. RAG数据简介
  3. PDF解析方法及工具
  4. 代码实现
  5. 总结

二、正文内容

  1. 引言

本文将介绍如何将RAG数据拆分至PDF格式,并探讨PDF解析的方法和工具,最后提供代码示例。

  1. RAG数据简介

RAG(关系型属性图)是一种用于表示实体及其关系的图数据结构。在RAG中,节点表示实体,边表示实体之间的关系,属性则用于描述实体和边的特征。

  1. PDF解析方法及工具

(1)PDF解析方法

  • DOM解析:将PDF文档转换为树形结构,便于操作和遍历。
  • SAX解析:基于事件驱动,适用于处理大型PDF文档。

(2)PDF解析工具

  • PyPDF2:一个Python库,用于读取、分割、合并PDF文件。
  • PDFMiner:一个强大的PDF解析库,支持提取文本、图片等元素。
  • pdfplumber:一个专注于文本提取的PDF解析库。
  1. 代码实现

以下是一个使用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.csdn.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格式
  1. 总结

本文介绍了RAG数据拆分至PDF的方法和工具,并通过代码示例展示了如何使用PyPDF2进行PDF文件拆分。在实际应用中,可根据需求选择合适的解析方法和工具。

希望这个分享笔记大纲和代码示例能帮助你完成你的分享笔记。在实际编写过程中,可以根据具体需求进行调整和优化。

相关推荐
~烈18 小时前
Acrobat Pro DC 便携精简版 PDF 专业处理工具安装教程
pdf·acrobat pro dc·pdf 专业处理工具
我不是QI18 小时前
Master PDF Editor 逆向复现
汇编·安全·pdf
蓝创工坊Blue Foundry19 小时前
多个同模板 PDF,怎样批量提取同一类字段到 Excel
运维·数据库·pdf·自动化·ocr·excel
asdzx672 天前
Python PDF 拆分实战指南:单页拆分与按需页码范围拆分
开发语言·python·pdf
慧都小妮子3 天前
Aspose.CAD for .NET 26.6 更新发布
pdf·.net·3d渲染·cad·pdf导出·ifc编辑
蝉蜕日记3 天前
AccumuPDF高级版 v2.57 | 视图文转换PDF,合并分割压缩
android·智能手机·pdf·生活·软件需求
蓝创工坊Blue Foundry3 天前
PDF 批量提取指定内容到 Excel:按字段整理多个 PDF 的方法
pdf·ocr·excel·文心一言·paddlepaddle·paddle
Am-Chestnuts3 天前
AI长回答批量导出PDF与长图:多轮内容整理和免费Markdown备份
人工智能·pdf·aigc
zyplayer-doc3 天前
研发接口文档怎么长期维护:zyplayer-doc把API、Markdown和变更记录放进同一个知识库
大数据·数据库·人工智能·笔记·pdf·ocr
蜡台3 天前
uniapp pdf文件预览组件
pdf·uni-app·合同·pdfh5