使用GPT-4o将PDF解析为Markdown的工具,实现pd...

智能科技扫地僧 2024-07-15 00:20:28

仅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 fileimport dotenvdotenv.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 generatedif __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部分代码。

0 阅读:0

智能科技扫地僧

简介:感谢大家的关注