专栏名称: 气象学家
【气象学家】公众号平台为您解读最新气象科研进展、分享气象实用编程技巧、追踪气象即时资讯。欢迎加入气象AI和Python交流群以及气象博士群!与5W+的专业人士一起交流互动!
目录
相关文章推荐
煮娱星球  ·  求求资本别再给我们喂粑粑了,行吗? ·  昨天  
犀牛娱乐  ·  前瞻《浪姐6》:今年又收割哪些话题? ·  2 天前  
贵阳晚报  ·  《哪吒2》“急急如律令”翻译成“biu ... ·  2 天前  
贵阳晚报  ·  《哪吒2》“急急如律令”翻译成“biu ... ·  2 天前  
Vlinkage  ·  Vlinkage指数 | 2月9日剧综网播指数 ·  3 天前  
煮娱星球  ·  榜妹热线 ... ·  3 天前  
51好读  ›  专栏  ›  气象学家

使用GPT-4o将 PDF 解析为 Markdown 的开源工具,实现pdf转word完美转档

气象学家  · 公众号  ·  · 2024-07-02 14:30

正文

第一时间获取气象科研资讯

气象学家 公众号 交流群

加入

293 行代码,它可以几乎完美地解析任何 PDF 文件,包括排版、数学公式、表格、图片和图表等内容,平均每页成本为 $0.013 ,如果有免费的api,那就是零成本。

工作原理:使用 PyMuPDF 库,首先对 PDF 进行解析出所有非文本区域,并做好标记 然后使用 GPT-4o 进行解析,得到 markdown 文件。

项目名称:gptpdf [1]

主程序

def parse_pdf(pdf_path, output_dir='./', api_key=None, base_url=None, model='gpt-4o', verbose=False, gpt_worker=1):

"""
解析PDF文件到markdown文件
:param pdf_path: pdf文件路径
:param output_dir: 输出目录。存储所有的图片和markdown文件
:param api_key: OpenAI API Key(可选)。如果未提供,则使用OPENAI_API_KEY环境变量。
:param base_url: OpenAI Base URL。(可选)。如果未提供,则使用OPENAI_BASE_URL环境变量。
:param model: OpenAI Vison LLM Model,默认为'gpt-4o'。您还可以使用qwen-vl-max
:param verbose: 详细模式,默认为False
:param gpt_worker: gpt解析工作线程数,默认为1
:return: (content, all_rect_images), markdown内容,带有![](path/to/image.png) 和 所有矩形图像(图像、表格、图表等)路径列表。
"""
import os
if not os.path.exists(output_dir):
os.makedirs(output_dir)

image_infos = _parse_pdf_to_images(pdf_path, output_dir=output_dir)
content = _gpt_parse_images(image_infos, output_dir=output_dir, api_key=api_key, base_url=base_url, model=model, verbose=verbose, gpt_worker=gpt_worker)

# 删除每页的图片 & 保留所有的矩形图片
all_rect_images = []
for page_image, rect_images in image_infos:
if os.path.exists(page_image):
os.remove(page_image)
all_rect_images.extend(rect_images)

return content, all_rect_images

用法

python 环境下直接安装 gptpdf

pip install gptpdf

在代码中直接导入 parse_pdf ,输入参数包括,输入 pdf 文件, gpt api 等,其他参数可以缺省。

import os
# laod environment variables from .env file
import dotenv
dotenv.load_dotenv()

def test_use_api_key():
from gptpdf import parse_pdf
pdf_path = '../examples/attention_is_all_you_need.pdf'
output_dir = '../examples/attention_is_all_you_need/'
api_key = os.getenv('OPENAI_API_KEY')
base_url = os.getenv('OPENAI_API_BASE')
# Manually provide OPENAI_API_KEY and OPEN_API_BASE
content, image_paths = parse_pdf(pdf_path, output_dir=output_dir, api_key=api_key, base_url=base_url, model='gpt-4o', gpt_worker=6)
print(content)
print(image_paths)
# also output_dir/output.md is generated

if __name__ == '__main__':
test_use_api_key()
# test_use_env()

如果使用代理 api 可以参数上加上 base_url

示例

原文件为:

解析出 markdown 格式为:

解析出 markdown 文件基本准确,可用性较高。

测试

cnki 下一篇文章,通过它来解析:

整体识别还是比较不错,个别地方是给出整张图片,没有解析文字。这个距离pdf转word已经很近了,可以直接把 markdown doc

markdown转doc

直接把 markdown 转成 doc 完成最后一步:

def markdown_to_docx(markdown_file, output_file):
# 读取Markdown文件内容,指定编码为GB2312
with open(markdown_file, 'r', encoding='gb2312') as f:
markdown_text = f.read()
# 使用mistune解析Markdown文本
html = mistune.markdown(markdown_text)

# 使用BeautifulSoup解析HTML
soup = BeautifulSoup(html, 'html.parser')

# 创建一个新的docx文档
doc = Document()

# 递归解析HTML并添加到docx文档中
def parse_html(element, parent):
if isinstance(element, NavigableString):
# 为纯文本创建一个段落并添加文本
new_paragraph = parent.add_paragraph()
new_paragraph.add_run(str(element))
elif element.name in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']:
# 添加标题
heading_level = int(element.name[1]) # heading level 1-6
new_paragraph = parent.add_heading(element.text.strip(), level=heading_level)
elif element.name == 'p':
# 添加段落
new_paragraph = parent.add_paragraph(element.text)
# 遍历段落内的img标签并处理图片
for img in element.find_all('img'):
img_src = img.get('src')
if img_src:
img_full_path = os.path.join(os.path.dirname(markdown_file), img_src)
if os.path.exists(img_full_path):
try:
# 添加图片到段落中
run = new_paragraph.add_run()
run.add_picture(img_full_path, width=Inches(4))
except Exception as e:
print(f"Error adding image: {e}")
else:
print(f"Warning: Image file '{img_full_path}' not found.")
elif element.name in ['ul', 'ol']:
# 添加列表项
bullet_style = 'ListBullet' if element.name == 'ul' else 'ListNumber'
for li in element.find_all('li'):
new_paragraph = parent.add_paragraph(li.text.strip(), style=bullet_style)
else:
# 递归处理其他元素
for child in element.children:
parse_html(child, parent)

# 遍历soup的子元素并解析
for element in soup.children:
parse_html(element, doc)
# 保存docx文档
doc.save(output_file)

转成 word 最后的效果:

现在的问题是 word 文档有好多空行,还有一些表,它把表以图的形式放在文档中,又通过gpt转成了表,后续作者优化应该可以解决。

脚本下载

如果上 github 不方便,可以后台回复 gptpdf 获取作者的代码,以及 markdown word 部分代码。

学习交流

我组了个『 OpenAI ChatGPT大模型交流群 』,如果对大模型感兴趣,加我微信,组大模型群拉上你。加微信时备注一下。现有已经有100多人入群了。

组建了『 PyQt6 学习交流1群 』快有1年了,大家积极交流,现在有 400 多位参与者,群内高手云集,各方面大咖,形成很好的 Python PyQt6 的交流生态,让我们借鉴,让我受益良多。群比较松散,开放进入就会比较乱,现在进群只能邀请,现在组建『 PyQt6 学习交流2群 』,如果需要进群,关注下面公众号,按提示进群。群内会不定期发放些学习材料、代码、视频等。

另外,如果我的文字对你有帮助,记得 点赞、转发,点在看

另外最近也有学习『 JavaScript 』组建『 🏅国际前端技术交流群 』 ,想组个群共同学习,感兴趣的可以加入学习讨论。

References

[1]

gptpdf: https://github.com/CosmosShadow/gptpdf/







声明:






请到「今天看啥」查看全文