采集内容插入词库( 如何用Python把许多PDF文件的文本内容批量提取出来)
优采云 发布时间: 2021-09-05 07:26采集内容插入词库(
如何用Python把许多PDF文件的文本内容批量提取出来)
本文将向您展示如何使用 Python 批量提取多个 PDF 文件的文本内容,并将它们组织起来并存储在一个数据框中,以供后续数据分析使用。
问题
最近,后台读者的评论变得更加多样化了。
文章写了几篇关于自然语言处理的文章后,声音越来越大:
老师,有没有什么方便的方法提取pdf中的文本内容?
我能感受到读者的心情。
在我展示的例子中,文本数据可以直接读入数据框工具进行处理。它们可能来自开放数据集合、网站API 或爬虫。
但是,有时您会遇到需要处理指定格式数据的问题。
例如,pdf。
许多学术论文、研究报告,甚至数据共享都是以这种格式发表的。
这时候,如果你掌握了很多自然语言分析工具,你就会有一种“拔剑望心”的感觉——你知道如何处理里面的文字信息,但是格式转换有问题。做不到。
怎么办?
当然也有方法,比如专用工具,在线转换服务网站,甚至手动复制粘贴。
但我们重视效率,对吗?
以上部分方式需要大量内容在线传输,耗时较长,并可能带来安全和隐私问题;有些需要特殊购买;有些根本不现实。
怎么办?
好消息是Python可以帮助您高效快速地批量提取pdf文本内容,并与数据整理分析工具无缝对接,为您后续的分析处理提供基础服务。
本文向您详细介绍了这个过程。
想试试吗?
数据
为了更好的说明过程,我为大家准备了一个压缩包。
包括本教程的代码和我们将使用的数据。
请到本网站下载与本教程匹配的压缩包。
下载后解压,在生成的目录(以下简称“demo目录”)中可以看到如下内容。
演示目录收录:
此外,demo 目录中还收录 2 个文件夹。
在这两个文件夹中,有中文pdf文件,用来展示pdf内容的提取。都是我几年前发表的中文核心期刊论文。
这里有两种解释:
我以我自己的论文为例,因为我怕用别人的论文进行文本提取会引起与论文作者和数据库运营商的知识产权纠纷;它分为2个文件夹,向您展示添加新pdf文件时提取工具会做什么?
pdf文件夹内容如下:
newpdf文件夹内容如下:
数据准备好了,我们来部署代码运行环境。
环境
要安装 Python,更简单的方法是安装 Anaconda 包。
请到此网站下载最新版本的 Anaconda。
请选择左侧的Python3.6版本进行下载安装。
如果您需要具体的分步说明,或者想知道如何在Windows平台上安装和运行Anaconda命令,请参考我为您准备的视频教程。
安装Anaconda后,打开终端,使用cd命令进入demo目录。
如果你不知道怎么使用,也可以参考视频教程。
我们需要安装一些环境相关的包。
先执行:
pip install pipenv
这里安装的是 pipenv,一个优秀的 Python 包管理工具。
安装完成后,请执行:
pipenv install --skip-lock
pipenv 工具会根据 Pipfile 自动安装我们需要的所有依赖软件包。
终端会有进度条,显示需要安装的软件数量和实际进度。
安装完成后,按照提示执行:
pipenv shell
这样,我们就进入了本教程专用的虚拟操作环境。
注意以下语句必须执行:
python -m ipykernel install --user --name=py36
只有这样,当前的Python环境才会在系统中注册为内核并命名为py36。
在此,请确保您的计算机上已安装 Google Chrome 浏览器。
我们执行:
jupyter notebook
将打开默认浏览器(谷歌浏览器)并启动 Jupyter notebook 界面:
可以直接点击文件列表中的第一个ipynb文件,查看本教程的所有示例代码。
你可以一边看教程讲解,一边一一执行这些代码。
但是,我建议的方法是返回主界面并创建一个新的空白 Python 3 notebook(显示名称为 py36 的 notebook)。
请按照教程一一输入相应内容。这可以帮助您更深入地理解代码的含义并更有效地内化您的技能。
当你在编写代码时遇到困难,你可以参考demo.ipynb文件。
准备工作结束,正式开始输入密码。
代码
首先,我们读入一些文件操作的模块。
import glob
import os
如上所述,demo目录下有两个文件夹,分别是pdf和newpdf。
我们将pdf文件的路径指定为其中的pdf文件夹。
pdf_path = "pdf/"
我们要获取所有pdf文件的路径。使用glob,一个命令就可以完成这个功能。
pdfs = glob.glob("{}/*.pdf".format(pdf_path))
检查我们得到的pdf文件的路径是否正确。
pdfs
['pdf/复杂系统仿真的微博客虚假信息扩散模型研究.pdf',
'pdf/面向影子分析的社交媒体竞争情报搜集.pdf',
'pdf/面向人机协同的移动互联网政务门户探析.pdf']
已验证。准确。
接下来,我们使用pdfminer从pdf文件中提取内容。我们需要从辅助Python文件pdf_extractor.py中读取函数extract_pdf_content。
from pdf_extractor import extract_pdf_content
使用此函数,我们尝试从pdf文件列表中的第一篇文章中提取内容并将文本保存在内容变量中。
content = extract_pdf_content(pdfs[0])
让我们看看内容:
content
显然内容提取不完善,混入了页眉页脚等信息。
然而,对于我们的许多文本分析目的来说,这并不重要。
你会在内容中看到很多\n。这是什么?
我们使用打印功能来显示内容的内容。
print(content)
可以清楚地看到那些\n是换行符。
我们通过 pdf 文件提取测试建立了信心。
接下来,我们应该建立一个字典,批量提取和存储内容。
mydict = {}
我们遍历pdfs列表,以文件名(不包括目录)作为key值。这样我们就可以很容易的看出哪些pdf文件已经解压了,哪些还没有解压。
为了使这个过程更清晰,我们让 Python 输出正在提取的 pdf 文件的名称。
for pdf in pdfs:
key = pdf.split('/')[-1]
if not key in mydict:
print("Extracting content from {} ...".format(pdf))
mydict[key] = extract_pdf_content(pdf)
在提取过程中,您将看到以下输出消息:
Extracting content from pdf/复杂系统仿真的微博客虚假信息扩散模型研究.pdf ...
Extracting content from pdf/面向影子分析的社交媒体竞争情报搜集.pdf ...
Extracting content from pdf/面向人机协同的移动互联网政务门户探析.pdf ...
看看此时字典中的键值是什么:
mydict.keys()
dict_keys(['复杂系统仿真的微博客虚假信息扩散模型研究.pdf', '面向影子分析的社交媒体竞争情报搜集.pdf', '面向人机协同的移动互联网政务门户探析.pdf'])
一切正常。
接下来我们调用pandas将字典变成数据框,方便分析。
import pandas as pd
下面这句话可以把字典转换成数据框。注意下面的reset_index()也是把原字典key值生成的索引转换成普通列。
df = pd.DataFrame.from_dict(mydict, orient='index').reset_index()
然后我们重命名了该列以备将来使用。
df.columns = ["path", "content"]
此时数据框的内容如下:
df
如您所见,我们的数据框收录 pdf 文件信息和所有文本内容。这样就可以使用关键词抽取、情感分析、相似度计算等多种分析工具。
限于篇幅,我们仅以字符计数为例来演示基本的分析功能。
我们让 Python 帮助我们计算提取内容的长度。
df["length"] = df.content.apply(lambda x: len(x))
此时数据框的内容有如下变化:
df
额外的一列是pdf文本内容中的字符数。
为了在 Jupyter Notebook 中正确显示绘图结果,我们需要使用以下语句:
%matplotlib inline
接下来,我们让 Pandas 用列图标显示一列字符长度的信息。为了美观,我们设置了图片的纵横比,将对应的pdf文件名以45度的倾斜度显示。
import matplotlib.pyplot as plt
plt.figure(figsize=(14, 6))
df.set_index('path').length.plot(kind='bar')
plt.xticks(rotation=45)
视觉分析完成。
接下来,我们将刚才的分析过程整理成函数,方便以后调用。
我们先把提取pdf内容的模块集成到字典中:
def get_mydict_from_pdf_path(mydict, pdf_path):
pdfs = glob.glob("{}/*.pdf".format(pdf_path))
for pdf in pdfs:
key = pdf.split('/')[-1]
if not key in mydict:
print("Extracting content from {} ...".format(pdf))
mydict[key] = extract_pdf_content(pdf)
return mydict
这里输入的是现有字典和pdf文件夹的路径。输出是一个新字典。
您可能想知道为什么您仍然需要输入“现有字典”。别着急,后面我会举一个实际的例子。
下面的函数非常简单——将字典转换为数据框。
def make_df_from_mydict(mydict):
df = pd.DataFrame.from_dict(mydict, orient='index').reset_index()
df.columns = ["path", "content"]
return df
最后一个函数用于绘制计数的字符数。
def draw_df(df):
df["length"] = df.content.apply(lambda x: len(x))
plt.figure(figsize=(14, 6))
df.set_index('path').length.plot(kind='bar')
plt.xticks(rotation=45)
函数已经编译好了,下面来试试吧。
记得demo目录下有一个子目录,叫newpdf吧?
我们将两个 pdf 文件移至 pdf 目录。
pdf目录下有5个文件:
我们执行三个新排序的函数。
先输入已有的字典(注意此时里面有3条记录),pdf文件夹路径没有变化。输出是新字典。
mydict = get_mydict_from_pdf_path(mydict, pdf_path)
Extracting content from pdf/微博客 Twitter 的企业竞争情报搜集.pdf ...
Extracting content from pdf/移动社交媒体用户隐私保护对策研究.pdf ...
注意这里的提示,原来的3个pdf文件没有再解压,只解压了2个新的pdf文件。
我们这里总共只有 5 个文件,所以您可能无法直观地感受到显着差异。
然而,假设你已经用了几个小时从数百个 pdf 文件中提取信息,结果你的老板扔给你 3 个新的 pdf 文件......
如果非要一开始就提取信息,恐怕会崩溃。
此时,使用我们的函数,您可以在 1 分钟内追加新的文件内容。
这个差别不小吧?
接下来,我们使用新字典来构建数据框。
df = make_df_from_mydict(mydict)
我们绘制一个新的数据框,pdf提取文本字符数。结果如下:
draw_df(df)
至此,代码展示完成。
总结
总结一下,本文为大家介绍了以下知识点:
讨论
在您之前的数据分析工作中,您是否遇到过从pdf文件中提取文本的任务?你是怎么处理的?有没有更好的工具和方法?欢迎留言,与大家分享你的经验和想法,我们一起交流讨论。