点击下方卡片,关注“小白玩转Python”公众号

PDF 解析和文本提取

首先,我们需要揭开的秘密是 PDF 解析和文本提取。你是否曾经想过如何从 PDF 中提取有用信息?别担心,Python 可以帮助你。我们可以使用像 PyPDF2、FPDF 和 reportlab 这样的神奇库来解析 PDF 文件,然后从中提取文本信息。

以下是 PyPDF2、FPDF 和 reportlab 库的介绍:

  • PyPDF2 库:PyPDF2 是一个用于处理 PDF 文件的 Python 库。它提供了包括合并、拆分、旋转、提取文本、提取页面、添加水印等在内的多种功能。你可以使用 PyPDF2 库来读取 PDF 文件的内容,并提取文本和图像;你还可以用它来创建新的 PDF 文件或修改现有的 PDF 文件。它是一个功能丰富且易于使用的库,适合各种 PDF 操作需求。

  • FPDF:FPDF 是一个用于创建 PDF 文件的 Python 库。它允许你使用 Python 代码生成包含文本、图像、表格图形等元素的标准 PDF 文档。FPDF 简单易用;适合基本的 PDF 生成需求。你可以使用 FDPF 来创建报告文档、证书、发票等。

  • reportlab:reportlab 是一个强大且灵活的 Python 库,用于创建复杂的 PDF 文档。它提供了丰富的功能来处理文本、图像、表格、图形、字体等,并支持高级布局和样式。reportlab 是一个广泛使用的库,适合生成专业的 PDF 报告、书籍、数据可视化等。

首先安装模块:

pip install PyPDF2 FPDF reportlab

安装完成后,你就可以愉快地玩转 PDF 文件了。

特别说明:在学习本模块的 API 时,需要注意一个问题。在 3.0.0 版本中,PdfFileReader、PdfFileWriter 和 PdfFileMerger 类将被移除。建议使用 PdfReader、PdfWriter 和 PdfMerger 代替。

我已经安装了 PyPDF2(版本 3.0.1),只有以下代码才能正确运行。大家需要注意版本兼容性问题。

import PyPDF2


# Open PDF file
with open('example.pdf', 'rb') as file:
  # Create a PDF reader object
  reader = PyPDF2.PdfReader(file)
  
  # Get the number of pages in a PDF file.
  num_pages = len(reader.pages)
  
  # Extract text content page by page and print.
  for page_num in range(num_pages):
    page = reader.pages[page_num]
    text = page.extract_text()
    print(text)

合并和拆分 PDF

接下来是我们的第二招:PDF 合并和拆分。想象一下,你手中有很多 PDF 文件,你可以使用 Python 轻松地将它们合并成一个整洁的 PDF,或者将一个大文件拆分成多个较小的文件。让我们试试这段有趣的代码:

from PyPDF2 import PdfMerger, PdfReader, PdfWriter


# Create a PDF merger
merger = PdfMerger()


# Merge multiple PDF files
merger.append('example.pdf')
merger.append('file2.pdf')


# Save the merged file.
merger.write('merged.pdf')
merger.close()


# Split a PDF file
with open('merged.pdf', 'rb') as file:
    reader = PdfReader(file)
    num_pages = len(reader.pages)
  
    # Split every 10 pages into one file.
    for start in range(0, num_pages, 10):
        end = min(start + 9, num_pages - 1)
        writer = PdfWriter()
    
        # Add specified range of pages to a new file.
        for page_num in range(start, end + 1):
            writer.add_page(reader.pages[page_num])
    
        # Save the split files.
        with open(f'part_{start+1}-{end+1}.pdf', 'wb') as output_file:
            writer.write(output_file)


print("Ta-da! The magic of merging and splitting is complete.!")

PDF 表单处理

第三项技能是 PDF 表单处理。我们都知道,填写大量 PDF 表单是一项非常繁琐的任务,但别担心,Python 的魔法助手在这里!我们可以使用像 PyPDF2、pdfw 和 FPDF 这样有趣的库来自动填写表单字段、读取填写的数据或生成全新的 PDF 表单。去试试吧!

from PyPDF2 import PdfReader, PdfWriter


from reportlab.pdfgen import canvas


# Automatically fill in form fields
def fill_form(input_file, output_file, data):
    c = canvas.Canvas(output_file)
    c.setFont("Helvetica", 12)
    
    # Read input file, process page by page.
    reader = PdfReader(input_file)
    for page_num, page in enumerate(reader.pages, start=1):
        # Obtain the size of the page and create a canvas of corresponding size.
        page_width = float(page.mediabox.width)
        page_height = float(page.mediabox.width)
        c.setPageSize((page_width, page_height))
        
        # Draw page content
        c.showPage()
        
        # Check if the page has form fields.
        if '/Annots' in page:
            # Traverse all form fields
            for annot in page['/Annots']:
                # Check the field type as text area.
                if '/T' in annot and '/V' in annot and annot['/Type'] == '/Annot':
                    field_name = annot['/T'][1:-1]  # Get field name
                    # Replace the field value with the incoming data.
                    if field_name in data:
                        field_value = data[field_name]
                        c.drawString(annot['/Rect'][0], annot['/Rect'][1], field_value)
    
    # Save the PDF with filled data.
    c.save()


# Read the filled data.
def read_form_data(input_file):
    data = {}
    reader = PdfReader(input_file)
    
    # Traverse all pages.
    for page in reader.pages:
        # Check if there are form fields.
        if '/Annots' in page:
            # Traverse all form fields
            for annot in page['/Annots']:
                # Check the field type as text area.
                if '/T' in annot and '/V' in annot and annot['/Type'] == '/Annot':
                    field_name = annot['/T'][1:-1]  # Get field name
                    field_value = annot['/V'][1:-1] if isinstance(annot['/V'], str) else ''
                    data[field_name] = field_value
    
    return data


# Create a new PDF form
def create_form(output_file, data):
    c = canvas.Canvas(output_file)
    c.setFont("Helvetica", 12)
    
    # Add data line by line to the form.
    y = 800
    for field, value in data.items():
        c.drawString(50, y, f"{field}: {value}")
        y -= 20
    
    # Save form
    c.save()


# Fill in the form fields and save.
fill_form('form_template.pdf', 'filled_form.pdf', {'name': 'joe', 'age': '18'})


# Read the filled data and print.
form_data = read_form_data('filled_form.pdf')
print(form_data)


# Create a new PDF form
create_form('my_form.pdf', {'name': 'joe', 'age': '18'})


print("Magic completed! Now you can easily handle PDF forms!")

PDF 文档转换

下一个魔法是 PDF 文档转换。有时 PDF 的格式可能不太方便,你可能想将 PDF 转换为其他格式,如图像、HTML 或纯文本。让我们一起探索转换的魔法吧!在将 PDF 文档转换为另一种格式时,你可以使用不同的库和工具来实现。以下是每种转换类型的理论解释以及相应的示例代码:

1. 将 PDF 转换为图像

要将 PDF 转换为图像,你可以使用 pdf2image 库。这个库可以将 PDF 页面转换为图像格式(如 JPEG、PNG 等)。以下是将 PDF 转换为图像的示例代码:

from pdf2image import convert_from_path


def pdf_to_image(input_file, output_file):
    images = convert_from_path(input_file)
    for i, image in enumerate(images):
        image.save(f'{output_file}_{i}.jpg', 'JPEG')


pdf_to_image('input.pdf', 'output_image')

你可以调用 pdf_to_image 函数将输入的 PDF 文件转换为图像,并以 JPEG 格式图像文件保存结果。

注意:如果你遇到 pdf2image.exceptions.PDFInfoNotInstalledError 错误消息。这个错误通常发生在缺少 poppler-utils 依赖时。要解决这个问题,请根据你的操作系统按照以下步骤操作:

Windows:

  1. 访问以下网站:

    https://github.com/oschwartz10612/poppler-windows/releases/

  2. 在“Assets”部分下载适合你的操作系统的 poppler-x.x.x_x 版本。

  3. 解压缩下载的文件,并将它的路径添加到系统环境变量中。

macOS:

通过 Homebrew 安装 Poppler。运行以下命令:

brew install poppler

Ubuntu/Debian:

安装 Poppler。运行以下命令:

sudo apt-get install poppler-utils

安装完成后,请重新启动你的 Python 环境,然后再次尝试运行 pdf_to_image 函数。这样,你将能够成功地将 PDF 转换为图像。

2. 将 PDF 转换为 HTML

如果你想将 PDF 文件转换为 HTML 格式,你可以使用支持 PDF 解析的库,如 PyPDF2。以下是将 PDF 转换为 HTML 的示例代码:

from PyPDF2 import PdfReader


def pdf_to_html(input_file, output_file):
    with open(input_file, 'rb') as file:
        reader = PdfReader(file)
        text = ""
        
        # Extract text content page by page
        for page in reader.pages:
            text += page.extract_text()
        
        # Save as HTML file
        with open(output_file, 'w') as html_file:
            html_file.write(f"<html><body>{text}</body></html>")


pdf_to_html('input.pdf', 'output.html')

你可以调用 pdf_to_html 函数将输入的 PDF 文件转换为 HTML 格式,并将结果保存到输出文件中。

3. 将 PDF 转换为纯文本

要将 PDF 转换为纯文本格式,你可以使用 pdfminer 库。它是一个从 PDF 文档中提取文本的强大工具。以下是将 PDF 转换为纯文本的示例代码:

pdfminer.six 库:这是 pdfminer 库的新版本,专门为 Python 3 编写。它是 PDF 解析的现代实现,并持续进行维护和更新。pdfminer.six 库兼容 Python 2 和 Python 3,因此它可以在 Python 的更新版本中使用,同时也支持一些较旧的版本。

安装依赖项:使用 pdfminer.six 库

pip install pdfminer.six

示例代码:

from pdfminer.high_level import extract_text_to_fp


def pdf_to_text(input_file, output_file):
    with open(output_file, 'w') as text_file:
        with open(input_file, 'rb') as file:
            extract_text_to_fp(file, text_file)


pdf_to_text('input.pdf', 'output.txt')

你可以调用 pdf_to_text 函数将输入的 PDF 文件转换为纯文本格式,并将结果保存到输出文件中。

4. 将 PDF 转换为 Word 文档

要将 PDF 转换为 Word 文档,你可以使用第三方库 python-docx,它可以用来创建和编辑 Word 文档。以下是 python-docx 库的介绍:

  • python-docx 库:python-docx 是一个用于创建和修改 Microsoft Word 文档的 Python 库。它提供了一个简单而强大的 API,允许你通过代码创建、修改和操作 Word 文档。使用 python-docx,你可以添加段落、字体样式、表格、图像等内容。你还可以修改现有文档的样式和内容。它支持 Word 2007 及更高版本的 docx 文件格式。

安装依赖项:

pip install python-docx PyPDF2

以下是将 PDF 转换为 Word 文档的示例代码:

from docx import Document
from PyPDF2 import PdfReader


def pdf_to_word(input_file, output_file):
    with open(input_file, 'rb') as file:
        reader = PdfReader(file)
        text = ""
        
        # Extract text content page by page
        for page in reader.pages:
            text += page.extract_text()
        
        # Create Word document
        doc = Document()
        doc.add_paragraph(text)
        
        # Save as Word document
        doc.save(output_file)


pdf_to_word('input.pdf', 'output.docx')

你可以调用 pdf_to_word 函数将输入的 PDF 文件转换为 Word 文档,并将结果保存到输出文件中。请确保在运行上述示例代码之前已安装相应的库和依赖项。你可以使用 pip 命令安装任何缺失的库。

PDF 水印和签名

接下来是 PDF 水印和数字签名的魔法!想象一下,为 PDF 文件添加水印或数字签名可以增强版权保护和安全性:

from PyPDF2 import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
import io


# Add watermark to PDF
def add_watermark(input_file, output_file, watermark_text):
    reader = PdfReader(input_file)
    writer = PdfWriter()


    watermark_buffer = io.BytesIO()


    # Create a PDF with watermark.
    c = canvas.Canvas(watermark_buffer)
    c.setFont("Helvetica", 48) # Pay attention to the choice of font.
    c.rotate(45)
    c.translate(-500, -500)
    c.setFillAlpha(0.3)
    c.drawString(400, 400, watermark_text)
    c.save()


    watermark_buffer.seek(0)
    watermark_pdf = PdfReader(watermark_buffer)


    # Traverse each page.
    for i, page in enumerate(reader.pages, start=1):
        watermark_page = watermark_pdf.pages[0]


        # Add watermark to the page
        page.merge_page(watermark_page)
        writer.add_page(page)


    # Save the file with watermark.
    with open(output_file, 'wb') as file:
        writer.write(file)


# Add digital signature to PDF
def add_signature(input_file, output_file, signature_image):
    reader = PdfReader(input_file)
    writer = PdfWriter()


    # Traverse each page.
    for i, page in enumerate(reader.pages, start=1):
        # Add a signature image to the bottom right corner of the page.
        page.merge_page(signature_image)
        writer.add_page(page)


    # Save the document with a signature.
    with open(output_file, 'wb') as file:
        writer.write(file)


# Use the functions add_watermark() and add_signature() to add watermark and signature.
watermark_text = "Confidential document, do not disclose."
signature_image = PdfReader("signature.pdf").pages[0]


add_watermark('part_21-30.pdf', 'document_with_watermark.pdf', watermark_text)
add_signature('document_with_watermark.pdf', 'document_with_watermark_and_signature.pdf', signature_image)


print("Watermark and signature magic completed! You can now make your PDF files more secure and professional!")

PDF 报告生成

现在,我们准备探索最后一块魔法!PDF 报告生成,想象一下使用 Python 的力量生成各种漂亮的 PDF 报告,包括图表、表格和文本。

依赖项安装:

pip install pytesseract
import matplotlib.pyplot as plt
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Table, Image
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import Paragraph, Spacer


# Create report content
def create_report(output_file, data):
    # Create PDF document object
    doc = SimpleDocTemplate(output_file, pagesize=A4)


    # Load stylesheet
    styles = getSampleStyleSheet()


    # Create report content elements
    elements = []


    # Add title
    title = Paragraph("Sales report", styles["Title"])
    elements.append(title)
    elements.append(Spacer(1, 20))


    # Add table
    table_data = data
    table = Table(table_data)
    elements.append(table)
    elements.append(Spacer(1, 20))


    # Generate charts and save as PNG images
    plt.plot(data[1][1:], marker='o')
    plt.xlabel("date")
    plt.ylabel("Sales revenue")
    plt.title("Sales Trend Chart")
    plt.savefig("sales_plot.png")
    plt.close()


    # Add charts to the report content.
    image = Image("sales_plot.png", width=400, height=300)
    elements.append(image)


    # Generate report
    doc.build(elements)


# Create report data
report_data = [
    ["date", "Sales revenue"],
    ["1/1", 100],
    ["1/2", 200],
    ["1/3", 150],
    ["1/4", 300],
]


# Generate report
create_report('sales_report.pdf', report_data)


print("Table generation completed! Now you can view the generated report file.")

OCR(光学字符识别)

最后一块魔法是 OCR(光学字符识别)。想象一下,你有一些扫描的 PDF 文档,需要将文本转换为可搜索和可编辑的文本。好消息是,Python 可以帮助你实现这一点!让我们一起体验这个神奇的咒语吧!

import pdf2image
import pytesseract


# Convert PDF to image
def pdf_to_image(input_file):
    images = pdf2image.convert_from_path(input_file)
    return images


# Use OCR to convert images into text.
def image_to_text(image):
    text = pytesseract.image_to_string(image)
    return text


# Save the text to a file
def save_text_to_file(text, output_file):
    with open(output_file, 'w', encoding='utf-8') as file:
        file.write(text)


# Extract text from PDF.
def extract_text_from_pdf(input_file, output_file):
    # Convert PDF to image
    images = pdf_to_image(input_file)
    
    extracted_text = ""
    
    # Extract text from each image.
    for image in images:
        text = image_to_text(image)
        extracted_text += text + "\n"
    
    # Save the extracted text to a file.
    save_text_to_file(extracted_text, output_file)


# Extract text from scanned PDF.
extract_text_from_pdf('scanned_document.pdf', 'extracted_text.txt')


print("OCR (Optical Character Recognition) magic completed! Now you can convert scanned PDF documents into editable text!")

·  END  ·

🌟 想要变身计算机视觉小能手?快来「小白玩转Python」公众号!

回复Python视觉实战项目,解锁31个超有趣的视觉项目大礼包!🎁

1ccb0fb785082ce3c7b51bb2e765947b.png

本文仅供学习交流使用,如有侵权请联系作者删除

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐