文档解析-pdf转markdown python实现方案

1,494 阅读8分钟

方案一:使用 PyMuPDF (fitz)

核心工具包

  • PyMuPDF (fitz): 一个强大的PDF解析库,能够按顺序提取PDF文档中的文本、图片、图表等对象。

步骤

  1. 打开PDF文件:使用 PyMuPDF 打开指定的PDF文件。
  2. 遍历PDF页面:逐页遍历PDF文档,获取每一页的内容。
  3. 提取页面内容:对于每一页,提取页面中的所有对象,包括文本、图片等,并根据对象在页面中的顺序进行处理。
    • 文本提取:提取文本块,并将其添加到最终的Markdown字符串中。
    • 图片提取:提取图片块,并生成Markdown格式的图片标记,保留图片的位置。
  4. 整合内容:将提取的内容按页面顺序整合成Markdown格式的字符串。
  5. 返回结果:最终将生成的Markdown字符串返回。

优势

  • PyMuPDF 能够精确识别和提取PDF中的各种对象,并保留它们在页面中的顺序。
  • 适合处理包含复杂布局和多种内容类型的PDF文档。

实现思路

使用 PyMuPDF 提取PDF页面的所有内容,确保每个对象(文本、图片等)按照它们在文档中的顺序提取并输出,然后将这些内容整合为Markdown格式的字符串。

代码示例

import os
import fitz  # PyMuPDF

def convert_to_md(user, doc_id, doc_path):
    pdf_path = os.path.join(BASE_DIR, doc_path)
    doc = fitz.open(pdf_path)
    content = ""

    for page_num in range(doc.page_count):
        page = doc.load_page(page_num)
        blocks = page.get_text("dict")["blocks"]
        
        for block in blocks:
            if block['type'] == 0:  # Text block
                for line in block['lines']:
                    for span in line['spans']:
                        content += span['text'] + "\n"
                content += "\n"
            elif block['type'] == 1:  # Image block
                # 保存图像并生成Markdown引用
                image_data = page.get_image(block['image'])
                image_filename = f"image_{doc_id}_{page_num}_{block['image']}.png"
                with open(image_filename, "wb") as img_file:
                    img_file.write(image_data)
                content += f"![Image](./{image_filename})\n"

    doc.close()
    return content

示例说明:

  • 文本提取:代码通过遍历每页中的文本块,将文本内容提取并转换为Markdown格式。
  • 图片提取:每当遇到图片块时,代码提取图片数据并将其保存为PNG文件,然后在Markdown中生成对应的图片引用。

方案二:使用 pdfplumberPyMuPDF

核心工具包

  • pdfplumber: 用于从PDF中提取文本、表格和图片。
  • PyMuPDF (fitz): 用于更精确地提取PDF中的图片和图表。

步骤

  1. 打开PDF文件:使用 pdfplumber 打开PDF文件,以便精确提取文本和表格。
  2. 逐页提取内容
    • 文本提取:从每一页中提取所有文本内容,包括段落和标题,并将其转换为Markdown格式。
    • 表格提取:检测并提取每页中的表格,将其转换为Markdown表格格式。
    • 图片提取:使用 PyMuPDF 提取嵌入的图片和图表,保留它们的位置。
  3. 整合提取内容:将提取的文本、表格和图片按页面顺序组合成Markdown格式。
  4. 返回结果:返回生成的Markdown字符串。

优势

  • pdfplumber 非常擅长处理和提取复杂的表格结构,与 PyMuPDF 的结合能够准确提取和保存图片和图表。
  • 该方案适用于需要同时处理文本、表格和图像的复杂PDF文档。

实现思路

首先使用 pdfplumber 提取文本和表格,然后使用 PyMuPDF 提取图像,最后将所有提取内容按顺序整合为Markdown字符串输出。

代码示例

import os
import pdfplumber
import fitz  # PyMuPDF

def convert_to_md(user, doc_id, doc_path):
    pdf_path = os.path.join(BASE_DIR, doc_path)
    content = ""

    with pdfplumber.open(pdf_path) as pdf:
        for page_num, page in enumerate(pdf.pages):
            # 提取文本
            text = page.extract_text()
            if text:
                content += text + "\n"
            
            # 提取表格
            tables = page.extract_tables()
            for table in tables:
                for row in table:
                    content += "| " + " | ".join(row) + " |\n"
                content += "\n"

            # 使用 PyMuPDF 提取图像
            pdf_document = fitz.open(pdf_path)
            page_fitz = pdf_document.load_page(page_num)
            images = page_fitz.get_images(full=True)
            for img in images:
                xref = img[0]
                base_image = pdf_document.extract_image(xref)
                image_bytes = base_image["image"]
                image_filename = f"image_{doc_id}_{page_num}_{xref}.png"
                with open(image_filename, "wb") as img_file:
                    img_file.write(image_bytes)
                content += f"![Image](./{image_filename})\n"

    return content

示例说明:

  • 文本提取:代码使用 pdfplumber 逐页提取文本内容,并将其转换为Markdown段落。
  • 表格提取:通过 pdfplumber 提取表格并将其格式化为Markdown表格。
  • 图片提取:使用 PyMuPDF 提取页面中的图片,将其保存为文件,并在Markdown中插入图片引用。

方案三:使用 pdfminer.sixPyMuPDF

核心工具包

  • pdfminer.six:用于解析PDF文档的文本内容,能够保留复杂的文本结构和格式。
  • PyMuPDF (fitz):用于处理和提取PDF中的图像、表格和图表,并保持其在文档中的顺序。

步骤

  1. 打开PDF文件:使用 pdfminer.six 解析PDF文件的文本内容。
  2. 逐页解析文本
    • 文本提取:提取页面中的文本块,保留段落、标题等格式,并转换为Markdown。
    • 表格和图片提取:使用 PyMuPDF 处理页面中的图片和表格,确保按页面顺序提取。
  3. 整合内容:将提取的文本、图片、表格按页面顺序组合为Markdown格式。
  4. 返回结果:返回生成的Markdown字符串。

优势

  • pdfminer.six 能够细致地解析文本结构,适合复杂文本格式的提取。
  • PyMuPDF 结合使用,可以精确地提取和处理非文本内容,确保所有内容按原始文档顺序输出。

实现思路

使用 pdfminer.six 提取文本并保留其格式,使用 PyMuPDF 提取非文本内容(如图片、表格),然后将所有内容按页面顺序整合为Markdown格式。

代码示例

import os
from pdfminer.high_level import extract_text
import fitz  # PyMuPDF

def convert_to_md(user, doc_id, doc_path):
    pdf_path = os.path.join(BASE_DIR, doc_path)
    content = ""

    # 使用 pdfminer.six 提取文本
    text = extract_text(pdf_path)
    if text:
        content += text + "\n"

    # 使用 PyMuPDF 提取图片和表格
    doc = fitz.open(pdf_path)
    for page_num in range(doc.page_count):
        page = doc.load_page(page_num)
        images = page.get_images(full=True)
        for img in images:
            xref = img[0]
            base_image = doc.extract_image(xref)
            image_bytes = base_image["image"]
            image_filename = f"image_{doc_id}_{page_num}_{xref}.png"
            with open(image_filename, "wb") as img_file:
                img_file.write(image_bytes)
            content += f"![Image](./{image_filename})\n"

    doc.close()
    return content

示例说明:

  • 文本提取:代码通过 pdfminer.six 提取并保留PDF中的文本格式,如段

落、标题等。

  • 图片提取:使用 PyMuPDF 提取图片并保存为文件,同时在Markdown中生成相应的图片标记。

方案四:使用 PyPDF2pdfplumber

核心工具包

  • PyPDF2:一个轻量级的PDF解析库,用于提取简单文本内容。
  • pdfplumber:用于提取PDF中的表格和图片,确保按页面顺序输出。

步骤

  1. 打开PDF文件:使用 PyPDF2 打开PDF文件,并按页面提取文本内容。
  2. 逐页提取内容
    • 文本提取:使用 PyPDF2 提取简单的文本内容,并转换为Markdown格式。
    • 表格提取:使用 pdfplumber 提取复杂的表格,并将其转换为Markdown表格。
    • 图片提取:使用 pdfplumber 提取图片,保存图片并生成Markdown标记。
  3. 整合提取内容:将文本、表格、图片按页面顺序组合成Markdown格式。
  4. 返回结果:返回最终的Markdown字符串。

优势

  • PyPDF2 易于使用,适合处理简单的文本提取任务。
  • pdfplumber 结合使用,能够处理复杂的表格和图片提取任务。

实现思路

首先使用 PyPDF2 提取简单的文本内容,然后使用 pdfplumber 处理表格和图片,最终将所有内容整合为Markdown输出。

代码示例

import os
import PyPDF2
import pdfplumber

def convert_to_md(user, doc_id, doc_path):
    pdf_path = os.path.join(BASE_DIR, doc_path)
    content = ""

    # 使用 PyPDF2 提取文本
    with open(pdf_path, 'rb') as f:
        reader = PyPDF2.PdfFileReader(f)
        for page_num in range(reader.getNumPages()):
            page = reader.getPage(page_num)
            content += page.extract_text() + "\n"

    # 使用 pdfplumber 提取表格和图片
    with pdfplumber.open(pdf_path) as pdf:
        for page_num, page in enumerate(pdf.pages):
            # 提取表格
            tables = page.extract_tables()
            for table in tables:
                for row in table:
                    content += "| " + " | ".join(row) + " |\n"
                content += "\n"

            # 提取图片
            images = page.images
            for img in images:
                # 保存图片并生成Markdown标记
                img_bbox = (img['x0'], img['top'], img['x1'], img['bottom'])
                img_filename = f"image_{doc_id}_{page_num}_{img['object_id']}.png"
                img_cropped = page.within_bbox(img_bbox).to_image()
                img_cropped.save(img_filename, format="PNG")
                content += f"![Image](./{img_filename})\n"

    return content

示例说明:

  • 文本提取:通过 PyPDF2 提取每一页的文本内容,适合处理简单文本。
  • 表格提取:使用 pdfplumber 提取表格,并将其格式化为Markdown表格。
  • 图片提取:通过 pdfplumber 提取图片,保存图片并生成对应的Markdown标记。

方案五:使用 pandocpypandoc

核心工具包

  • pypandoc:Python的 pandoc 接口,用于将PDF转换为其他格式。
  • pandoc:强大的文档转换工具,支持将PDF文件转换为Markdown格式。

步骤

  1. 安装并配置pandoc:确保系统中安装了 pandoc 并配置正确。
  2. 使用pypandoc转换文件
    • 调用 pypandoc 将PDF文件直接转换为Markdown格式。
    • pandoc 会自动处理文本、图片等内容,并生成Markdown输出。
  3. 返回Markdown内容:直接返回由 pandoc 生成的Markdown内容。

优势

  • pandoc 是一个强大的文档转换工具,能够高效地将PDF转换为Markdown格式。
  • 适合需要快速转换和处理的场景,无需手动提取和处理内容。

实现思路

使用 pypandoc 作为接口,调用 pandoc 将PDF文档转换为Markdown格式,最后将转换结果返回。

代码示例

import os
import pypandoc

def convert_to_md(user, doc_id, doc_path):
    pdf_path = os.path.join(BASE_DIR, doc_path)
    
    # 使用 pypandoc 将 PDF 转换为 Markdown
    output = pypandoc.convert_file(pdf_path, 'md')
    
    return output

示例说明:

  • 快速转换:通过调用 pandoc,可以快速将PDF文档转换为Markdown格式。
  • 自动处理pandoc 会自动处理文档中的文本、图片等内容,生成标准的Markdown输出。

以上五种方案详细介绍了如何从PDF文档中提取内容,并将其转换为Markdown格式。根据具体需求选择合适的方案,可以确保最大限度地保留文档的原始顺序和格式。