赞
踩
参考Python使用PyPDF2库进行PDF文件操作的详细教程-腾讯云开发者社区-腾讯云
- pythonCopy codeimport PyPDF2
-
- def extract_text(pdf_file):
- with open(pdf_file, 'rb') as file:
- pdf_reader = PyPDF2.PdfFileReader(file)
- text = ''
-
- for page_num in range(pdf_reader.numPages):
- text += pdf_reader.getPage(page_num).extractText()
-
- return text
-
- # 使用示例
- pdf_file = 'sample.pdf'
- text_content = extract_text(pdf_file)
- print(text_content)
这段代码定义了一个名为 extract_text
的函数,其目的是从一个PDF文件中提取文本内容。这个函数接受一个参数 pdf_file
,这个参数预期是一个字符串,表示PDF文件的路径。下面是对这段代码的详细解释:
with open(pdf_file, 'rb') as file:
这一行使用Python的with
语句来打开一个文件。with
语句确保文件在使用后会被正确关闭,即使在处理文件时发生异常也是如此。open
函数的第一个参数pdf_file
是文件路径,它由函数的输入参数提供。第二个参数'rb'
是模式参数,表示以“二进制只读模式”打开文件。这是读取二进制文件(如PDF)所必需的。as file
部分将打开的文件对象赋值给变量file
,以便在代码块中使用。
pdf_reader = PyPDF2.PdfFileReader(file)
这一行使用PyPDF2
库创建了一个PdfFileReader
对象。这个对象用于读取PDF文件的内容。PyPDF2.PdfFileReader
是PyPDF2
库中用于解析PDF文件的类。我们将这个对象赋值给变量pdf_reader
。
text = ''
这里初始化一个空字符串text
,它将用于累积从PDF的每一页提取的文本。
for page_num in range(pdf_reader.numPages):
这是一个for
循环,它遍历pdf_reader
中的所有页面。pdf_reader.numPages
属性返回PDF文件中的页面总数。range
函数创建一个从0开始到页面总数(不包括总数)的整数序列,每个整数代表一个页面的编号。
text += pdf_reader.getPage(page_num).extractText()
在循环内部,我们使用pdf_reader
对象的getPage
方法来获取当前页面(由page_num
指定)。然后,我们调用extractText
方法来提取当前页面的文本内容。extractText
方法返回一个字符串,包含页面上的所有文本。我们使用+=
操作符将这个字符串追加到text
变量中。
return text
最后,当所有页面的文本都被提取并累积到text
变量后,函数返回这个字符串。这意味着,函数的调用者将收到一个包含整个PDF文件文本内容的字符串。
需要注意的是,extractText
方法的效果可能因PDF文件的不同而有所差异。
但是文档字数过多,全部提取会造成大量的信息冗余,因此需要截取特定字符串之间的数据
- # 示例字符串
- string = "Hello, World! This is an example string."
-
- # 查找子字符串的索引位置
- index = string.find("This is")
-
- # 获取特定子字符串之后的字符串
- result = string[index + len("This is"):]
-
- print(result)
- import PyPDF2
-
- def extract_text_between_substring(file_path, start_str, end_str):
- with open(file_path, 'rb') as file:
- pdf_reader = PyPDF2.PdfFileReader(file)
- text = ""
- for page_num in range(pdf_reader.numPages):
- page = pdf_reader.getPage(page_num)
- pdf_text = page.extract_text()
-
- # 查找起始字符串和结束字符串的索引
- start_index = pdf_text.find(start_str)
- end_index = pdf_text.find(end_str)
-
- # 如果两个索引都存在,则提取之间的文本
- 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
-
- return text
-
- # 使用示例
- 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)
这段代码定义了一个名为 extract_text_between_substring
的函数,它使用 PyPDF2
库来从 PDF 文件中提取两个指定字符串之间的文本内容。这个函数可以处理多个 PDF 文件,并对每个文件执行相同的提取操作。以下是对这段代码的详细解释:
导入 PyPDF2
库:
import PyPDF2
这行代码导入了 PyPDF2
库,这是一个用于处理 PDF 文件的 Python 库。
定义 extract_text_between_substring
函数:
def extract_text_between_substring(file_path, start_str, end_str):
这个函数接受三个参数:file_path
是 PDF 文件的路径,start_str
是要查找的起始字符串,end_str
是要查找的结束字符串。
使用 with
语句打开 PDF 文件:
with open(file_path, 'rb') as file:
with
语句确保文件在操作完成后会被正确关闭。'rb'
模式表示以二进制方式读取文件,这对于处理二进制格式的 PDF 文件是必要的。
创建 PyPDF2.PdfFileReader
对象:
pdf_reader = PyPDF2.PdfFileReader(file)
这个对象用于读取 PDF 文件的内容。
初始化一个空字符串 text
来存储提取的文本:
text = ""
遍历 PDF 文件的每一页:
for page_num in range(pdf_reader.numPages):
pdf_reader.numPages
属性返回 PDF 文件中的页面总数,for
循环遍历每一页。
获取当前页面的文本内容:
page = pdf_reader.getPage(page_num) pdf_text = page.extract_text()
extract_text()
方法用于提取页面的文本内容。
查找起始字符串和结束字符串的索引:
start_index = pdf_text.find(start_str) end_index = pdf_text.find(end_str)
提取两个字符串之间的文本:
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
变量中。
返回累积的文本:
return text
函数返回从每一页中提取的所有文本的组合。
使用示例:
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 技术来提取文本。
- import os
- import fnmatch
-
- def get_files_with_pattern(directory, pattern):
- matched_files = []
- for root, dirs, files in os.walk(directory):
- for file in files:
- if fnmatch.fnmatch(file, pattern):
- matched_files.append(os.path.join(root, file))
- return matched_files
-
- # 使用示例
- directory = '/path/to/your/directory' # 替换为您的目录路径
- pattern = '*中期票据募集说明书*' # 替换为您要匹配的模式
- file_list = get_files_with_pattern(directory, pattern)
-
- # 打印文件列表
- for file in file_list:
- print(file)
在这个示例中,get_files_with_pattern
函数接受两个参数:directory
是您想要搜索的目录路径,pattern
是您想要匹配的文件名模式。函数使用os.walk()
来遍历目录及其所有子目录,并通过fnmatch.fnmatch()
来检查每个文件名是否匹配给定的模式。
- for page_num in range(len(pdf_reader.pages)):
- page = pdf_reader.pages(page_num)
- 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
虚拟列表中的每一项,而不是尝试调用它。以下是修改后的代码:
- for page_num in range(len(pdf_reader.pages)):
- page = pdf_reader.pages[page_num] # 正确的访问方式
- pdf_text = page.extract_text()
- # ... 处理文本 ...
在这个修改后的代码中,我们使用 pdf_reader.pages[page_num]
来获取第 page_num
页的内容,而不是尝试调用 pdf_reader.pages(page_num)
。这样就可以避免 TypeError
并正确地从 PDF 文件的每一页提取文本了。
运行结果如图:
截取的是目录部分,很显然不是我们需要的
代码如下:
- import re
-
- def extract_text_between_second_occurrences(file_path, start_str, end_str, middle_str):
- # 读取文件内容
- with open(file_path, 'r', encoding='utf-8') as file:
- text = file.read()
-
- # 找到目标字符串的所有出现位置
- matches = re.finditer(re.escape(start_str) + '.*?' + re.escape(middle_str) + '.*?' + re.escape(end_str), text)
-
- # 如果找到匹配,并且至少有两次出现,则提取第二次出现的文本
- for i, match in enumerate(matches):
- if i == 1: # 第二次出现
- start_index = match.end(len(start_str))
- end_index = match.start(len(start_str) + len(middle_str))
- between_text = text[start_index:end_index]
- return between_text
-
- return "没有找到第二次出现的模式。"
- start_str = "第二章"
- end_str = "第三章"
- middle_str = "利率风险"
-
- for pdf_file in pdf_list:
- between_text = extract_text_between_second_occurrences(pdf_file, start_str, end_str, middle_str)
- print(between_text)
-
是编码选择错误
发现是ANSI格式,更改代码
- with open(file_path, 'r', encoding='ANSI') as file:
- text = file.read()
表示在尝试使用 MBCS(多字节字符集)编码读取文件时,遇到了无法映射到目标代码页的字节序列。
修改代码
- # 检测文件编码
- with open(file_path, 'rb') as file:
- content = file.read()
- result = chardet.detect(content)
- encoding = result['encoding']
-
- # 使用检测到的编码读取文件
- with open(file_path, 'r', encoding=encoding) as file:
- text = file.read()
仍然报错,只能选择忽略
- # 用替代字符替换无法解码的字节
- with open('file_path', 'r', encoding='gbk', errors='replace') as file:
- content = file.read()
可是最终结果仍然是失败,可能因为re正则表达式无法匹配编码格式
- import PyPDF2
-
- def extract_text_between_second_occurrence(pdf_path, start_str, middle_str, end_str):
- # 初始化文本内容和出现位置列表
- full_text = ""
- occurrence_positions = []
-
- # 打开PDF文件
- with open(pdf_path, 'rb') as pdf_file:
- pdf_reader = PyPDF2.PdfReader(pdf_file)
-
- # 遍历PDF的每一页并提取文本
- for page_num in range(len(pdf_reader.pages)):
- page = pdf_reader.pages[page_num]
- text = page.extract_text()
- full_text += text # 添加到完整文本内容
- position = full_text.find(start_str) # 查找起始字符串的位置
- if position != -1:
- occurrence_positions.append(position) # 添加到出现位置列表
-
- # 检查起始字符串是否至少出现了两次
- if len(occurrence_positions) < 2:
- return "起始字符串出现次数不足两次。"
-
- # 找到第二次出现的起始位置和结束位置
- second_start = occurrence_positions[1]
- first_end = occurrence_positions[0] + len(start_str)
-
- # 提取两次出现之间的文本
- between_text = full_text[first_end:second_start]
-
- return between_text
运行结果为空集。可能还是编码问题
pdfminer.six
库提取PDF文本- from pdfminer.high_level import extract_text
-
- def extract_text_between_second_occurrence_with_pdfminer(pdf_path, start_str, end_str):
- text = extract_text(pdf_path)
- start_positions = [m.start() for m in re.finditer(start_str, text)]
- end_positions = [m.start() for m in re.finditer(end_str, text)]
-
- if len(start_positions) < 2 or len(end_positions) < 2:
- return "起始字符串或结束字符串出现次数不足两次。"
-
- # 找到第二次出现的位置
- second_start = start_positions[1]
- second_end = end_positions[1]
-
- # 提取中间文本
- between_text = text[second_start:second_end]
-
- return between_text
-
- # 使用示例
- pdf_path = 'example.pdf' # 替换为您的PDF文件路径
- start_str = "我" # 起始字符串
- end_str = "你" # 结束字符串
-
- # 调用函数并打印结果
- result = extract_text_between_second_occurrence_with_pdfminer(pdf_path, start_str, end_str)
- print(result)
终于得出文档内容
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。