2026年7月2日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


收藏

GPT-4o 自动化提取PDF的内容:以雅思真题4为例

发布日期:2024-06-06 06:59:08 浏览次数: 3342
作者:机智流

微信搜一搜,关注“机智流”


同类任务迁移

    在前两期的内容中我带大家了解了如何使用 GPT-4o 辅助编程以便从“剑雅4” PDF 中检索并提取雅思听力真题,并对部分代码进行了讲解。其实就对整体的检索工作流程有了一些基础的认知了,下面我就通过提取该雅思阅读的内容来带大家看看我是如何通过修改同一个提示词,来根据我工作的要求进行个性化定制。大家可以关注「机智流」后回复“雅思”或点击文末的“阅读原文”来获取这份文档的内容。

⚠️ 温馨提醒

在使用前,建议不要在原有的聊天界面中继续完成任务,尽可能新开一个页面消除记忆,因为假如有之前的记忆很容易出问题。

任务解析

    雅思阅读和听力有点不同,就是其不是说 Section 了,说的是 READING PASSAGE 1、2&3 了。因此我们的关键词需要修改一下。而且只有三篇而不是四篇。并且命名规则假如和之前重合也不好,所以这些都是需要修改的地方。但是总体而言差别不大。

    但是即便有之前的完整代码,我建议还是像之前一样三步走而不是一步到位,因为大模型的输出还是不太可控,我尝试了两次都失败了,但是利用任务拆分的方法都是一次就成功了。

第一步:提取一个PASSAGE

    因此我在原本的提示词基础上进行了修改,包括把之前听力时候提取的代码作为案例给到这次的提示词里,并且把对应需要修改的部分也处理了。完整的提示词如下所示:

###任务说明###
那首先,这里有一份剑桥雅思 4 的 pdf 文件。我现在希望做的事情是,当使用 python 的 fitz 库时:
1. 先查找“Test 1”,再查找“READING”(Test 1 和 READING 可能隔得有点远,但是肯定是最接近的一个 READING了)
2. 然后在查找到“READING PASSAGE 1”后,开始读取其内部的内容
3. 直到读取到了“READING PASSAGE 2”,停止内容的读取,并将中间的内容读取出来。
请你给出完整的代码并用代码编辑器进行测试
请一步步思考后给出完整的代码。
你可以参考以下提取LISTENING部分的代码

###提取LISTENING部分的代码###
import fitz  # PyMuPDF

# 打开 PDF 文件
pdf_document = '/mnt/data/剑桥雅思4 高清原版.pdf'
pdf = fitz.open(pdf_document)

# 定义查找的关键词
keywords = ["Test 1""LISTENING""SECTION 1""SECTION 2"]

# 初始化状态变量
found_test = False
found_listening = False
found_section1 = False
found_section2 = False
content = []

# 遍历每一页
for page_num in range(pdf.page_count):
    page = pdf[page_num]
    text = page.get_text()

    # 查找 "Test 1"
    if not found_test:
        if keywords[0in text:
            found_test = True
    # 查找 "LISTENING"
    if found_test and not found_listening:
        if keywords[1in text:
            found_listening = True
    # 查找 "SECTION 1"
    if found_test and found_listening and not found_section1:
        if keywords[2in text:
            found_section1 = True
    # 开始读取内容
    if found_test and found_listening and found_section1:
        lines = text.split('\n')
        for line in lines:
            # 检查是否到达 "SECTION 2"
            if keywords[3in line:
                found_section2 = True
                break
            content.append(line)
        # 如果找到 "SECTION 2",停止读取
        if found_section2:
            break

# 打印读取的内容
content_text = "\n".join(content)
content_text

    最终也是得到了一个非常近似于之前听力部分的代码,只不过是在关键词部分修改了一点。并且是一次就成功实现,并没有像听力的时候还出现了错误。从这里我们就可以看出大语言模型真的可以模仿之前的代码风格进行撰写。假如我们能够使用一些few-shot的提示词技巧是真的可以提升大语言模型的准确率。

    提取雅思阅读部分的完整代码如下所示:

import fitz  # PyMuPDF

# 打开 PDF 文件
pdf_document = '/mnt/data/剑桥雅思4 高清原版.pdf'
pdf = fitz.open(pdf_document)

# 定义查找的关键词
keywords = ["Test 1""READING""READING PASSAGE 1""READING PASSAGE 2"]

# 初始化状态变量
found_test = False
found_reading = False
found_passage1 = False
content = []

# 遍历每一页
for page_num in range(pdf.page_count):
    page = pdf[page_num]
    text = page.get_text()

    # 查找 "Test 1"
    if not found_test:
        if keywords[0in text:
            found_test = True
    
    # 查找 "READING"
    if found_test and not found_reading:
        if keywords[1in text:
            found_reading = True
    
    # 查找 "READING PASSAGE 1"
    if found_test and found_reading and not found_passage1:
        if keywords[2in text:
            found_passage1 = True
    
    # 开始读取内容
    if found_test and found_reading and found_passage1:
        lines = text.split('\n')
        for line in lines:
            # 检查是否到达 "READING PASSAGE 2"
            if keywords[3in line:
                break
            content.append(line)
        
        # 如果找到 "READING PASSAGE 2",停止读取
        if keywords[3in text:
            break

# 打印读取的内容
content_text = "\n".join(content)
content_text

第二步:扩展到所有的 PASSAGE

    那第二步我们也是类似的修改了这部分代码,以下是鉴别这些 READING PASSAGE 的提示词:

###任务说明###
现在我想要提取整个 Test 1 里 READING 部分的内容(总共有3个PASSAGE)。
第一个 PASSAGE 的提取方式就是刚刚那样读取到“Test 1”、“READING”和“READING PASSAGE 1”,直到“READING PASSAGE 1”结束。
那第二个 PASSAGE 的开始就是“READING PASSAGE 2”直到“READING PASSAGE 3”结束。
那第三个SECTION就是从“READING PASSAGE 3”开始到“WRITING”结束。(就是READING PASSAGE 3紧接着的下一个WRITING,这个PDF里可能有很多的WRITING,但是我只考虑最接近的下一个WRITING)。

最后你要给出的是不同PASSAGE的md文件。分别保存在不同的位置处。

请一步步思考后给出完整的代码并使用代码编辑器测试。

    这一部分同样也是一次就生成了正确的代码,并且也通过了代码解释器的检验。

    生成的完整代码如下所示:

import fitz  # PyMuPDF

# 打开 PDF 文件
pdf_document = '/mnt/data/剑桥雅思4 高清原版.pdf'
pdf = fitz.open(pdf_document)

# 定义查找的关键词
keywords = ["Test 1""READING""READING PASSAGE 1""READING PASSAGE 2""READING PASSAGE 3""WRITING"]

# 初始化状态变量
found_test = False
found_reading = False
found_passage1 = False
found_passage2 = False
found_passage3 = False
content = {"READING PASSAGE 1": [], "READING PASSAGE 2": [], "READING PASSAGE 3": []}

# 遍历每一页
for page_num in range(pdf.page_count):
    page = pdf[page_num]
    text = page.get_text()

    # 查找 "Test 1"
    if not found_test:
        if keywords[0in text:
            found_test = True
    
    # 查找 "READING"
    if found_test and not found_reading:
        if keywords[1in text:
            found_reading = True
    
    # 查找 "READING PASSAGE 1"
    if found_test and found_reading and not found_passage1:
        if keywords[2in text:
            found_passage1 = True
    
    # 查找 "READING PASSAGE 2"
    if found_test and found_reading and found_passage1 and not found_passage2:
        lines = text.split('\n')
        for line in lines:
            if keywords[3in line:
                found_passage2 = True
                break
            content["READING PASSAGE 1"].append(line)
    
    # 查找 "READING PASSAGE 3"
    if found_test and found_reading and found_passage2 and not found_passage3:
        lines = text.split('\n')
        for line in lines:
            if keywords[4in line:
                found_passage3 = True
                break
            content["READING PASSAGE 2"].append(line)
    
    # 查找 "WRITING"
    if found_test and found_reading and found_passage3:
        lines = text.split('\n')
        for line in lines:
            if keywords[5in line:
                break
            content["READING PASSAGE 3"].append(line)
        
        # 如果找到 "WRITING",停止读取
        if keywords[5in text:
            break

# 保存内容到不同的md文件
for passage, lines in content.items():
    with open(f"/mnt/data/{passage}.md""w", encoding="utf-8"as file:
        file.write("\n".join(lines))

# 返回保存的文件路径
saved_files = [f"/mnt/data/{passage}.md" for passage in content]
saved_files

第三步:扩展到所有的 TEST

    最后我们也是修改了一些命名的规则,然后给出类似的提示词指令:

###任务说明###
非常好,你这个都成功提取出来了,那下一步我要把每一个Test里的 READING 的部分都提取出来。
一个雅思真题里都有 4 个 Test,每个 Test 都有 3 个 PASSAGE,我希望你能将每个 PASSAGE 都提取为单独的一个 md 文件。
不同 TEST 的不同 PASSAGE 的标题是 T1P1、T1P2、T1P3、T2P1,以此类推直到 T4P3。

GPT-4o同样是非常精准的完成了其任务,并且也给出了所有的文件。这里我就没有让继续检查是否空白文件了,因为阅读统一都是三篇,没有出现两篇或者四篇的情况发生。

    完整的代码如下所示:

# 打开 PDF 文件
pdf_document = '/mnt/data/剑桥雅思4 高清原版.pdf'
pdf = fitz.open(pdf_document)

# 定义查找的关键词
keywords = ["Test 1""Test 2""Test 3""Test 4""READING""READING PASSAGE 1""READING PASSAGE 2""READING PASSAGE 3""WRITING"]

# 初始化状态变量
found_test = [False] * 4
found_reading = False
found_passage1 = False
found_passage2 = False
found_passage3 = False
content = {"T1P1": [], "T1P2": [], "T1P3": [], "T2P1": [], "T2P2": [], "T2P3": [], "T3P1": [], "T3P2": [], "T3P3": [], "T4P1": [], "T4P2": [], "T4P3": []}
current_test = -1
current_passage = ""

# 遍历每一页
for page_num in range(pdf.page_count):
    page = pdf[page_num]
    text = page.get_text()
    
    # 查找 Test 1-4
    for i in range(4):
        if not found_test[i] and keywords[i] in text:
            found_test[i] = True
            current_test = i + 1
            break
    
    # 查找 "READING"
    if found_test[current_test - 1and not found_reading:
        if keywords[4in text:
            found_reading = True
    
    # 查找 "READING PASSAGE 1"
    if found_reading and not found_passage1:
        if keywords[5in text:
            found_passage1 = True
            current_passage = f"T{current_test}P1"
    
    # 查找 "READING PASSAGE 2"
    if found_passage1 and not found_passage2:
        lines = text.split('\n')
        for line in lines:
            if keywords[6in line:
                found_passage2 = True
                current_passage = f"T{current_test}P2"
                break
            content[f"T{current_test}P1"].append(line)
    
    # 查找 "READING PASSAGE 3"
    if found_passage2 and not found_passage3:
        lines = text.split('\n')
        for line in lines:
            if keywords[7in line:
                found_passage3 = True
                current_passage = f"T{current_test}P3"
                break
            content[f"T{current_test}P2"].append(line)
    
    # 查找 "WRITING"
    if found_passage3:
        lines = text.split('\n')
        for line in lines:
            if keywords[8in line:
                break
            content[f"T{current_test}P3"].append(line)
        
        # 如果找到 "WRITING",重置状态以查找下一个 Test
        if keywords[8in text:
            found_reading = False
            found_passage1 = False
            found_passage2 = False
            found_passage3 = False

# 保存内容到不同的md文件
for passage, lines in content.items():
    with open(f"/mnt/data/{passage}.md""w", encoding="utf-8"as file:
        file.write("\n".join(lines))

# 返回保存的文件路径
saved_files = [f"/mnt/data/{passage}.md" for passage in content]
saved_files

小结

    在这部分任务中,我们成功实现了从PDF中提取雅思阅读部分的内容,并通过分步法提高了代码的准确性。首先,我们修改了原有代码的关键词,以适应雅思阅读的结构,然后在每一步测试中逐步扩展代码,从提取单个PASSAGE到提取整个Test中的所有PASSAGE,最后完成了所有Test的提取工作。通过这种方法,我们确保了每一步的准确性,并最终生成了所有Test的阅读部分的Markdown文件。这一过程展示了大语言模型在处理文档解析任务中的灵活性和高效性,同时也证明了通过任务拆分和逐步测试可以显著提高代码的可靠性和成功率。

总结

    总的来说,在本文中,首先介绍了利用编程简化PDF内容提取的重要性,以及如何借助GPT-4o生成代码并进行测试。通过任务拆分和逐步测试的方法,从提取单个SECTION的内容开始,逐步扩展到提取整个Test中的所有SECTION,再到处理阅读部分的内容,最终生成了各自的Markdown文件。

    另外,文章还详细解析了代码的每一部分,包括关键词定义、状态变量初始化、遍历每一页的内容提取、内容保存到Markdown文件中的步骤,以及删除空白内容的处理。这一过程不仅展示了大语言模型在处理复杂文档解析任务中的灵活性和高效性,还证明了通过逐步引导和任务分解可以显著提高代码生成的成功率,为批量处理和自动化文档分析提供了有效的解决方案。


?点击阅读原文,获取「剑雅4」PDF原件

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅