Skip to content
Phone animation 宇宙尽头的餐馆

用 Python 批量修改 PDF 文件名

写了个小脚本能根据PDF内容自动用AI重命名。

· 4 min

写了个小脚本能根据PDF内容自动用AI重命名。

例如"附件(1).pdf"能根据内容变成"2023年用户访谈总结.pdf"

带 OCR 功能,PDF 不是文本也可以识别并改名。

效果如图:

白嫖党必不可能用 openai,当然是选择 Gemini 啦(要我给 openai 二次付费,不可能😤)

翻了一下 Gemini API 文档,发现它已经支持 OpenAI 格式的 API 调用,在 ChatGPT 老师的帮助下20分钟搞定 blobcat:blobcatsnapped 让我们感谢 ChatGPT 老师让我等根本不懂码的同学实现 python 自由!

更新日志
实现思路 & To Do
  • 实现思路灰常的简单:读取 PDF 文件,传给 Gemini,生成文件标题并修改
  • 未来可能各种文件类型都可以安排上,以及 prompt 还可以继续优化一下。

代码放在 GitHub:infinitesum/PDFs-Smart-Rename

访问不了 GitHub 可以继续往下看:

获取 Gemini API Key#

注意事项

代码#

你需要修改的部分

注意事项

1、操作不可撤销!!!请不要像我一样把整个路径的 PDF 都丢进去。。(在开始的 30s 我还在为一个个转换成功的提示而沾沾自喜,下一秒就意识到了事情的不对🌚此操作还是在我加 OCR 功能之前,类目……)如果实在是手抖不小心点到请务必按 ctrl+c before all hell breaks loose 🥹

分为批量重命名版和单文件版:

批量重命名版#

import os
import fitz # PyMuPDF
import pytesseract
from openai import OpenAI
from PIL import Image
# 配置Tesseract的路径,如果需要的话
# pytesseract.pytesseract.tesseract_cmd = r'<full_path_to_your_tesseract_executable>'
def extract_text_from_pdf(pdf_path, max_pages=3, min_text_length=100, max_text_length=3000):
"""
从PDF文件的前几页提取文本,如果文本不足则尝试OCR。
参数:
pdf_path (str): PDF文件路径
max_pages (int): 最多提取的页数
min_text_length (int): 最小文本长度,低于此值会尝试OCR
max_text_length (int): 最大文本长度,用于限制发送给AI的内容量
返回:
str: 提取的文本
"""
all_text = ""
ocr_needed = False
with fitz.open(pdf_path) as doc:
# 限制页数范围
page_count = min(len(doc), max_pages)
# 首先尝试从所有页面提取文本
for page_num in range(page_count):
page = doc[page_num]
page_text = page.get_text()
all_text += page_text + "\n\n"
# 如果已经有足够的文本,就不再提取更多
if len(all_text) >= min_text_length:
break
# 如果提取的文本量不足,尝试OCR
if len(all_text) < min_text_length:
ocr_needed = True
all_text = "" # 重置文本,重新通过OCR提取
for page_num in range(page_count):
page = doc[page_num]
pix = page.get_pixmap()
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
page_text = pytesseract.image_to_string(img)
all_text += page_text + "\n\n"
# 如果已经有足够的文本,就不再提取更多
if len(all_text) >= min_text_length:
break
# 截取一定长度的文本,避免发送过多内容
if len(all_text) > max_text_length:
all_text = all_text[:max_text_length] + "..."
print(f"文本提取{'使用OCR' if ocr_needed else '无需OCR'},总长度: {len(all_text)} 字符")
return all_text
def generate_title_with_gemini(pdf_text, api_key):
"""使用Gemini API根据PDF文本内容生成文件标题。"""
client = OpenAI(
api_key=api_key,
base_url="https://generativelanguage.googleapis.com/v1beta/openai/"
) # 替换为你的Gemini API密钥 和你自己的代理地址
prompt = "Suggest a title for the following document content in its original language, if it's a research or science paper, just extract the relevant information and name it like: author&author-publishyear-originaltitle. show el.al for multiple authors:"
# 将提示和PDF文本内容结合
full_text = prompt + "\n" + pdf_text
response = client.chat.completions.create(
model="gemini-2.0-flash",
messages=[
{"role": "user", "content": full_text}
]
)
if hasattr(response, 'choices') and len(response.choices) > 0:
return response.choices[0].message.content.strip()
return ""
def rename_pdf(pdf_path, api_key):
"""
提取PDF文本,使用Gemini生成标题,并重命名PDF文件。
"""
pdf_text = extract_text_from_pdf(pdf_path)
new_title = generate_title_with_gemini(pdf_text, api_key) + ".pdf"
new_path = os.path.join(os.path.dirname(pdf_path), new_title)
if not os.path.exists(new_path): # 确保不会覆盖已存在的文件
os.rename(pdf_path, new_path)
print(f"文件已重命名为: {new_path}")
else:
print("已存在同名文件,未执行重命名。")
def rename_pdfs_in_directory(directory_path, api_key):
"""
遍历指定目录中的所有PDF文件,并尝试重命名它们。
"""
for filename in os.listdir(directory_path):
if filename.lower().endswith('.pdf'):
pdf_path = os.path.join(directory_path, filename)
print(f"处理文件:{pdf_path}")
try:
rename_pdf(pdf_path, api_key)
except Exception as e:
print(f"处理文件 {pdf_path} 时发生错误:{e}")
# 批量重命名目录下的PDF文件
# 请替换以下变量中的占位符
directory_path = "/Users/summer/Downloads/1" # 替换为你的PDF文件目录
your_api_key = "YOUR_GEMINI_API_KEY" # 替换为你的Gemini API密钥
rename_pdfs_in_directory(directory_path, your_api_key)

单文件版#

import os
import fitz # PyMuPDF
import pytesseract
from openai import OpenAI
from PIL import Image
def extract_text_from_pdf(pdf_path, max_pages=3, min_text_length=100, max_text_length=3000):
"""
从PDF文件的前几页提取文本,如果文本不足则尝试OCR。
参数:
pdf_path (str): PDF文件路径
max_pages (int): 最多提取的页数
min_text_length (int): 最小文本长度,低于此值会尝试OCR
max_text_length (int): 最大文本长度,用于限制发送给AI的内容量
返回:
str: 提取的文本
"""
all_text = ""
ocr_needed = False
with fitz.open(pdf_path) as doc:
# 限制页数范围
page_count = min(len(doc), max_pages)
# 首先尝试从所有页面提取文本
for page_num in range(page_count):
page = doc[page_num]
page_text = page.get_text()
all_text += page_text + "\n\n"
# 如果已经有足够的文本,就不再提取更多
if len(all_text) >= min_text_length:
break
# 如果提取的文本量不足,尝试OCR
if len(all_text) < min_text_length:
ocr_needed = True
all_text = "" # 重置文本,重新通过OCR提取
for page_num in range(page_count):
page = doc[page_num]
pix = page.get_pixmap()
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
page_text = pytesseract.image_to_string(img)
all_text += page_text + "\n\n"
# 如果已经有足够的文本,就不再提取更多
if len(all_text) >= min_text_length:
break
# 截取一定长度的文本,避免发送过多内容
if len(all_text) > max_text_length:
all_text = all_text[:max_text_length] + "..."
print(f"文本提取{'使用OCR' if ocr_needed else '无需OCR'},总长度: {len(all_text)} 字符")
return all_text
def generate_title_with_gemini(pdf_text, api_key):
"""使用Gemini API根据PDF文本内容生成文件标题。"""
client = OpenAI(
api_key=api_key,
base_url="https://generativelanguage.googleapis.com/v1beta/openai/"
)
prompt = "Suggest a title for the following document content in its original language, if it's a research or science paper, just extract the relevant information and name it like: author&author-publishyear-originaltitle. show el.al for multiple authors:"
# 将提示和PDF文本内容结合
full_text = prompt + "\n" + pdf_text
response = client.chat.completions.create(
model="gemini-2.0-flash",
messages=[
{"role": "user", "content": full_text}
]
)
if hasattr(response, 'choices') and len(response.choices) > 0:
return response.choices[0].message.content.strip()
return ""
def rename_pdf(pdf_path, api_key):
"""提取PDF文本,使用Gemini生成标题,并重命名PDF文件。"""
pdf_text = extract_text_from_pdf(pdf_path)
new_title = generate_title_with_gemini(pdf_text, api_key) + ".pdf"
new_path = os.path.join(os.path.dirname(pdf_path), new_title)
if not os.path.exists(new_path): # 确保不会覆盖已存在的文件
os.rename(pdf_path, new_path)
print(f"文件已重命名为: {new_path}")
else:
print("已存在同名文件,未执行重命名。")
# 单个PDF文件路径
pdf_file_path = "/Users/summer/Downloads/1.pdf" # 请替换为你的PDF文件路径
your_api_key = "YOUR_GEMINI_API_KEY" # 替换为你的Gemini API密钥
rename_pdf(pdf_file_path, your_api_key)
> cd ..