当前位置:   article > 正文

python代码解析|提取多个pdf中指定文段的信息_批量提取pdf文件特定内容

批量提取pdf文件特定内容

 1提取pdf的所有内容

参考Python使用PyPDF2库进行PDF文件操作的详细教程-腾讯云开发者社区-腾讯云

  1. pythonCopy codeimport PyPDF2
  2. def extract_text(pdf_file):
  3. with open(pdf_file, 'rb') as file:
  4. pdf_reader = PyPDF2.PdfFileReader(file)
  5. text = ''
  6. for page_num in range(pdf_reader.numPages):
  7. text += pdf_reader.getPage(page_num).extractText()
  8. return text
  9. # 使用示例
  10. pdf_file = 'sample.pdf'
  11. text_content = extract_text(pdf_file)
  12. print(text_content)

这段代码定义了一个名为 extract_text 的函数,其目的是从一个PDF文件中提取文本内容。这个函数接受一个参数 pdf_file,这个参数预期是一个字符串,表示PDF文件的路径。下面是对这段代码的详细解释:

  1. with open(pdf_file, 'rb') as file:

    这一行使用Python的with语句来打开一个文件。with语句确保文件在使用后会被正确关闭,即使在处理文件时发生异常也是如此。open函数的第一个参数pdf_file是文件路径,它由函数的输入参数提供。第二个参数'rb'是模式参数,表示以“二进制只读模式”打开文件。这是读取二进制文件(如PDF)所必需的。as file部分将打开的文件对象赋值给变量file,以便在代码块中使用。

  2. pdf_reader = PyPDF2.PdfFileReader(file)

    这一行使用PyPDF2库创建了一个PdfFileReader对象。这个对象用于读取PDF文件的内容。PyPDF2.PdfFileReaderPyPDF2库中用于解析PDF文件的类。我们将这个对象赋值给变量pdf_reader

  3. text = ''

    这里初始化一个空字符串text,它将用于累积从PDF的每一页提取的文本。

  4. for page_num in range(pdf_reader.numPages):

    这是一个for循环,它遍历pdf_reader中的所有页面。pdf_reader.numPages属性返回PDF文件中的页面总数。range函数创建一个从0开始到页面总数(不包括总数)的整数序列,每个整数代表一个页面的编号。

  5. text += pdf_reader.getPage(page_num).extractText()

    在循环内部,我们使用pdf_reader对象的getPage方法来获取当前页面(由page_num指定)。然后,我们调用extractText方法来提取当前页面的文本内容。extractText方法返回一个字符串,包含页面上的所有文本。我们使用+=操作符将这个字符串追加到text变量中。

  6. return text

    最后,当所有页面的文本都被提取并累积到text变量后,函数返回这个字符串。这意味着,函数的调用者将收到一个包含整个PDF文件文本内容的字符串。

需要注意的是,extractText方法的效果可能因PDF文件的不同而有所差异。


但是文档字数过多,全部提取会造成大量的信息冗余,因此需要截取特定字符串之间的数据

2切片提取指定文字

  1. # 示例字符串
  2. string = "Hello, World! This is an example string."
  3. # 查找子字符串的索引位置
  4. index = string.find("This is")
  5. # 获取特定子字符串之后的字符串
  6. result = string[index + len("This is"):]
  7. print(result)

3提取多个文件中的指定字符串中的文字

  1. import PyPDF2
  2. def extract_text_between_substring(file_path, start_str, end_str):
  3. with open(file_path, 'rb') as file:
  4. pdf_reader = PyPDF2.PdfFileReader(file)
  5. text = ""
  6. for page_num in range(pdf_reader.numPages):
  7. page = pdf_reader.getPage(page_num)
  8. pdf_text = page.extract_text()
  9. # 查找起始字符串和结束字符串的索引
  10. start_index = pdf_text.find(start_str)
  11. end_index = pdf_text.find(end_str)
  12. # 如果两个索引都存在,则提取之间的文本
  13. if start_index != -1 and end_index != -1 and start_index < end_index:
  14. between_text = pdf_text[start_index + len(start_str):end_index]
  15. text += between_text
  16. return text
  17. # 使用示例
  18. pdf_files = ['file1.pdf', 'file2.pdf']
  19. start_str = "开始字符串"
  20. end_str = "结束字符串"
  21. for pdf_file in pdf_files:
  22. between_text = extract_text_between_substring(pdf_file, start_str, end_str)
  23. print(between_text)

这段代码定义了一个名为 extract_text_between_substring 的函数,它使用 PyPDF2 库来从 PDF 文件中提取两个指定字符串之间的文本内容。这个函数可以处理多个 PDF 文件,并对每个文件执行相同的提取操作。以下是对这段代码的详细解释:

  1. 导入 PyPDF2 库:

    import PyPDF2

    这行代码导入了 PyPDF2 库,这是一个用于处理 PDF 文件的 Python 库。

  2. 定义 extract_text_between_substring 函数:

    def extract_text_between_substring(file_path, start_str, end_str):

    这个函数接受三个参数:file_path 是 PDF 文件的路径,start_str 是要查找的起始字符串,end_str 是要查找的结束字符串。

  3. 使用 with 语句打开 PDF 文件:

    with open(file_path, 'rb') as file:

    with 语句确保文件在操作完成后会被正确关闭。'rb' 模式表示以二进制方式读取文件,这对于处理二进制格式的 PDF 文件是必要的。

  4. 创建 PyPDF2.PdfFileReader 对象:

    pdf_reader = PyPDF2.PdfFileReader(file)

    这个对象用于读取 PDF 文件的内容。

  5. 初始化一个空字符串 text 来存储提取的文本:

    text = ""
  6. 遍历 PDF 文件的每一页:

    for page_num in range(pdf_reader.numPages):

    pdf_reader.numPages 属性返回 PDF 文件中的页面总数,for 循环遍历每一页。

  7. 获取当前页面的文本内容:

    page = pdf_reader.getPage(page_num) pdf_text = page.extract_text()

    extract_text() 方法用于提取页面的文本内容。

  8. 查找起始字符串和结束字符串的索引:

    start_index = pdf_text.find(start_str) end_index = pdf_text.find(end_str)
  9. 提取两个字符串之间的文本:

    if start_index != -1 and end_index != -1 and start_index < end_index: between_text = pdf_text[start_index + len(start_str):end_index] text += between_text

    如果起始字符串和结束字符串都被找到,并且起始索引位于结束索引之前,则使用切片操作提取它们之间的文本。提取的文本被追加到 text 变量中。

  10. 返回累积的文本:

    return text

    函数返回从每一页中提取的所有文本的组合。

  11. 使用示例:

    pdf_files = ['file1.pdf', 'file2.pdf'] start_str = "开始字符串" end_str = "结束字符串" for pdf_file in pdf_files: between_text = extract_text_between_substring(pdf_file, start_str, end_str) print(between_text)

    这部分代码展示了如何使用定义的函数。它定义了一个 PDF 文件列表 pdf_files,以及要查找的起始和结束字符串。然后,它遍历文件列表,对每个文件调用 extract_text_between_substring 函数,并打印提取的文本。

需要注意的是,extract_text() 方法可能不会总是返回准确的文本,特别是对于包含复杂布局或图形元素的 PDF 文件。此外,如果 PDF 文件是加密的或者文本被渲染为图像,这种方法可能不适用,需要使用 OCR 技术来提取文本。


4提取文件夹中指定的文件形成list

  1. import os
  2. import fnmatch
  3. def get_files_with_pattern(directory, pattern):
  4. matched_files = []
  5. for root, dirs, files in os.walk(directory):
  6. for file in files:
  7. if fnmatch.fnmatch(file, pattern):
  8. matched_files.append(os.path.join(root, file))
  9. return matched_files
  10. # 使用示例
  11. directory = '/path/to/your/directory' # 替换为您的目录路径
  12. pattern = '*中期票据募集说明书*' # 替换为您要匹配的模式
  13. file_list = get_files_with_pattern(directory, pattern)
  14. # 打印文件列表
  15. for file in file_list:
  16. print(file)

在这个示例中,get_files_with_pattern函数接受两个参数:directory是您想要搜索的目录路径,pattern是您想要匹配的文件名模式。函数使用os.walk()来遍历目录及其所有子目录,并通过fnmatch.fnmatch()来检查每个文件名是否匹配给定的模式。


错误提示1'_VirtualList' object is not callable

  1. for page_num in range(len(pdf_reader.pages)):
  2. page = pdf_reader.pages(page_num)
  3. pdf_text = page.extract_text()

运行结果显示错误:TypeError: '_VirtualList' object is not callable

PyPDF2 库中,PdfFileReader 对象的 pages 属性是一个虚拟列表,可以通过索引来访问,但它并不是一个函数,所以不能像函数那样被调用。错误提示 TypeError: '_VirtualList' object is not callable 就是因为尝试像调用函数那样调用了 pdf_reader.pages(page_num)

正确的方式是直接使用索引来访问 pages 虚拟列表中的每一项,而不是尝试调用它。以下是修改后的代码:

  1. for page_num in range(len(pdf_reader.pages)):
  2. page = pdf_reader.pages[page_num] # 正确的访问方式
  3. pdf_text = page.extract_text()
  4. # ... 处理文本 ...

在这个修改后的代码中,我们使用 pdf_reader.pages[page_num] 来获取第 page_num 页的内容,而不是尝试调用 pdf_reader.pages(page_num)。这样就可以避免 TypeError 并正确地从 PDF 文件的每一页提取文本了。

运行结果如图:

截取的是目录部分,很显然不是我们需要的


4提取特定字符串第二次出现时的中间文本

代码如下:

  1. import re
  2. def extract_text_between_second_occurrences(file_path, start_str, end_str, middle_str):
  3. # 读取文件内容
  4. with open(file_path, 'r', encoding='utf-8') as file:
  5. text = file.read()
  6. # 找到目标字符串的所有出现位置
  7. matches = re.finditer(re.escape(start_str) + '.*?' + re.escape(middle_str) + '.*?' + re.escape(end_str), text)
  8. # 如果找到匹配,并且至少有两次出现,则提取第二次出现的文本
  9. for i, match in enumerate(matches):
  10. if i == 1: # 第二次出现
  11. start_index = match.end(len(start_str))
  12. end_index = match.start(len(start_str) + len(middle_str))
  13. between_text = text[start_index:end_index]
  14. return between_text
  15. return "没有找到第二次出现的模式。"
  1. start_str = "第二章"
  2. end_str = "第三章"
  3. middle_str = "利率风险"
  4. for pdf_file in pdf_list:
  5. between_text = extract_text_between_second_occurrences(pdf_file, start_str, end_str, middle_str)
  6. print(between_text)

错误提示2:'utf-8' codec can't decode byte 0xe2 in position 10: invalid continuation byte

是编码选择错误

发现是ANSI格式,更改代码

  1. with open(file_path, 'r', encoding='ANSI') as file:
  2. text = file.read()

错误提示3:'mbcs' codec can't decode bytes in position 0--1: No mapping for the Unicode character exists in the target code page.

表示在尝试使用 MBCS(多字节字符集)编码读取文件时,遇到了无法映射到目标代码页的字节序列。

修改代码

  1. # 检测文件编码
  2. with open(file_path, 'rb') as file:
  3. content = file.read()
  4. result = chardet.detect(content)
  5. encoding = result['encoding']
  6. # 使用检测到的编码读取文件
  7. with open(file_path, 'r', encoding=encoding) as file:
  8. text = file.read()

仍然报错,只能选择忽略

  1. # 用替代字符替换无法解码的字节
  2. with open('file_path', 'r', encoding='gbk', errors='replace') as file:
  3. content = file.read()

可是最终结果仍然是失败,可能因为re正则表达式无法匹配编码格式

5换用pypdf2处理

  1. import PyPDF2
  2. def extract_text_between_second_occurrence(pdf_path, start_str, middle_str, end_str):
  3. # 初始化文本内容和出现位置列表
  4. full_text = ""
  5. occurrence_positions = []
  6. # 打开PDF文件
  7. with open(pdf_path, 'rb') as pdf_file:
  8. pdf_reader = PyPDF2.PdfReader(pdf_file)
  9. # 遍历PDF的每一页并提取文本
  10. for page_num in range(len(pdf_reader.pages)):
  11. page = pdf_reader.pages[page_num]
  12. text = page.extract_text()
  13. full_text += text # 添加到完整文本内容
  14. position = full_text.find(start_str) # 查找起始字符串的位置
  15. if position != -1:
  16. occurrence_positions.append(position) # 添加到出现位置列表
  17. # 检查起始字符串是否至少出现了两次
  18. if len(occurrence_positions) < 2:
  19. return "起始字符串出现次数不足两次。"
  20. # 找到第二次出现的起始位置和结束位置
  21. second_start = occurrence_positions[1]
  22. first_end = occurrence_positions[0] + len(start_str)
  23. # 提取两次出现之间的文本
  24. between_text = full_text[first_end:second_start]
  25. return between_text

运行结果为空集。可能还是编码问题

6用pdfminer.six 库提取PDF文本

  1. from pdfminer.high_level import extract_text
  2. def extract_text_between_second_occurrence_with_pdfminer(pdf_path, start_str, end_str):
  3. text = extract_text(pdf_path)
  4. start_positions = [m.start() for m in re.finditer(start_str, text)]
  5. end_positions = [m.start() for m in re.finditer(end_str, text)]
  6. if len(start_positions) < 2 or len(end_positions) < 2:
  7. return "起始字符串或结束字符串出现次数不足两次。"
  8. # 找到第二次出现的位置
  9. second_start = start_positions[1]
  10. second_end = end_positions[1]
  11. # 提取中间文本
  12. between_text = text[second_start:second_end]
  13. return between_text
  14. # 使用示例
  15. pdf_path = 'example.pdf' # 替换为您的PDF文件路径
  16. start_str = "我" # 起始字符串
  17. end_str = "你" # 结束字符串
  18. # 调用函数并打印结果
  19. result = extract_text_between_second_occurrence_with_pdfminer(pdf_path, start_str, end_str)
  20. print(result)

终于得出文档内容

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/804209
推荐阅读
相关标签
  

闽ICP备14008679号