写了个小脚本能根据PDF内容自动用AI重命名。
例如"附件(1).pdf"能根据内容变成"2023年用户访谈总结.pdf"
带 OCR 功能,PDF 不是文本也可以识别并改名。
效果如图:
白嫖党必不可能用 openai,当然是选择 Gemini 啦(要我给 openai 二次付费,不可能😤)
翻了一下 Gemini API 文档,发现它已经支持 OpenAI 格式的 API 调用,在 ChatGPT 老师的帮助下20分钟搞定
让我们感谢 ChatGPT 老师让我等根本不懂码的同学实现 python 自由!
更新日志
- 2025-04-15 更新:才发现 Gemini API 可以通过 OpenAI 库来访问了,只需要修改几行代码就可以了。参考链接:https://ai.google.dev/gemini-api/docs/openai?hl=zh-cn
- 2024-04-01 更新防风控,不再通过
google-generativeai
库来访问了,尝试通过自己设置地址访问(用了CF Worker 的默认地址)。参考链接:https://zhile.io/2023/12/24/gemini-pro-proxy.html
实现思路 & To Do
- 实现思路灰常的简单:读取 PDF 文件,传给 Gemini,生成文件标题并修改
- 未来可能各种文件类型都可以安排上,以及 prompt 还可以继续优化一下。
代码放在 GitHub:infinitesum/PDFs-Smart-Rename
访问不了 GitHub 可以继续往下看:
获取 Gemini API Key#
- 打开 https://makersuite.google.com/
- 用 Google 账号登录
- 点击
Get API Key
->Create API key in new project
保存好 key
注意事项
- 目前该服务不支持香港IP,查看支持的区域
- 由于 IP (如多人共享 IP)或者频率的关系,可能会被谷歌云判定为滥用,导致 API Key 或者 谷歌云账户被禁用,请谨慎使用,或者使用小号。
代码#
你需要修改的部分
your_api_key
:替换为你的 Gemini API 密钥directory_path
:替换为你的 PDF 文件目录(或者替换pdf_file_path
为你的 PDF 文件路径)base_url
:如果你有自己的代理地址可以替换成自己的,或者使用上面网站提到的 CF Workers 代理地址。
注意事项
1、操作不可撤销!!!请不要像我一样把整个路径的 PDF 都丢进去。。(在开始的 30s 我还在为一个个转换成功的提示而沾沾自喜,下一秒就意识到了事情的不对🌚此操作还是在我加 OCR 功能之前,类目……)如果实在是手抖不小心点到请务必按 ctrl+c
before all hell breaks loose 🥹
分为批量重命名版和单文件版:
批量重命名版#
import osimport fitz # PyMuPDFimport pytesseractfrom openai import OpenAIfrom 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 osimport fitz # PyMuPDFimport pytesseractfrom openai import OpenAIfrom 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)