资讯专栏INFORMATION COLUMN

数据分析遇到PDF文本,怎么用Python批量提取内容

cloud / 2215人阅读

摘要:复杂系统仿真的微博客虚假信息扩散模型研究面向影子分析的社交媒体竞争情报搜集面向人机协同的移动互联网政务门户探析经验证。微博客的企业竞争情报搜集移动社交媒体用户隐私保护对策研究注意这里的提示,原先的个文件没有被再次抽取,只有个新文件被抽取。

本文为你展示,如何用Python把许多PDF文件的文本内容批量提取出来,并且整理存储到数据框中,以便于后续的数据分析。

问题

最近,读者们在后台的留言,愈发五花八门了。

写了几篇关于自然语言处理的文章后,一种呼声渐强:

pdf中的文本内容,有没有什么方便的方法提取出来呢?

我能体会到读者的心情。

我展示的例子中,文本数据都是直接可以读入数据框工具做处理的。它们可能来自开放数据集合、网站API,或者爬虫。

但是,有的时候,你会遇到需要处理指定格式数据的问题。

例如pdf。

许多的学术论文、研究报告,甚至是资料分享,都采用这种格式发布。

这时候,已经掌握了诸多自然语言分析工具的你,会颇有“拔剑四顾心茫然”的感觉——明明知道如何处理其中的文本信息,但就是隔着一个格式转换的问题,做不来。

怎么办?

办法自然是有的,例如专用工具、在线转换服务网站,甚至还可以手动复制粘贴嘛。

但是,咱们是看重效率的,对不对?

上述办法,有的需要在网上传输大量内容,花费时间较多,而且可能带来安全和隐私问题;有的需要专门花钱购买;有的干脆就不现实。

怎么办?

好消息是,Python就可以帮助你高效、快速地批量提取pdf文本内容,而且和数据整理分析工具无缝衔接,为你后续的分析处理做好基础服务工作。

数据

为了更好地说明流程,我为你准备好了一个压缩包。

里面包括本教程的代码,以及我们要用到的数据。

请你到 这个网址 下载本教程配套的压缩包。

下载后解压,你会在生成的目录(下称“演示目录”)里面看到以下内容。

演示目录里面包含:

Pipfile: pipenv 配置文件,用来准备咱们变成需要用到的依赖包。后文会讲解使用方法;
pdf_extractor.py: 利用pdfminer.six编写的辅助函数。有了它你就可以直接调用pdfminer提供的pdf文本内容抽取功能,而不必考虑一大堆恼人的参数;
demo.ipynb: 已经为你写好的本教程 Python 源代码 (Jupyter Notebook格式)。
另外,演示目录中还包括了2个文件夹。

这两个文件夹里面,都是中文pdf文件,用来给你展示pdf内容抽取。

pdf文件夹内容如下:

newpdf文件夹内容如下:

代码

首先,我们读入一些模块,以进行文件操作。

import glob
import os

前文提到过,演示目录下,有两个文件夹,分别是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 变量里。

content = extract_pdf_content(pdfs[0])

我们看看 content 里都有什么:

content


显然,内容抽取并不完美,页眉页脚等信息都混了进来。

不过,对于我们的许多文本分析用途来说,这无关紧要。

你会看到 content 的内容里面有许多的 n,这是什么呢?

我们用 print 函数,来显示 content 的内容。

print(content)

可以清楚看到,那些 n 是换行符。

通过一个 pdf 文件的抽取测试,我们建立了信心。

下面,我们该建立辞典,批量抽取和存储内容了。

mydict = {}

我们遍历 pdfs 列表,把文件名称(不包含目录)作为键值。这样,我们可以很容易看到,哪些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()把原先字典键值生成的索引也转换成了普通的列。

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度来展示。

如果对Python编程、网络爬虫、机器学习、数据挖掘、web开发、人工智能、面试经验交流。感兴趣可以519970686,群内会有不定期的发放免费的资料链接,这些资料都是从各个技术网站搜集、整理出来的,如果你有好的学习资料可以私聊发我,我会注明出处之后分享给大家。

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)

函数已经编好,下面我们来尝试一下。

还记得演示目录下有个子目录,叫做newpdf对吧?

我们把其中的2个pdf文件,移动到pdf目录下面。

这样pdf目录下面,就有了5个文件:

我们执行新整理出的3个函数。

首先输入已有的词典(注意此时里面已有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)

小结

总结一下,本文为你介绍了以下知识点:

如何用glob批量读取目录下指定格式的文件路径;
如何用pdfminer从pdf文件中抽取文本信息;
如何构建词典,存储与键值(本文中为文件名)对应的内容,并且避免重复处理数据;
如何将词典数据结构轻松转换为Pandas数据框,以便于后续数据分析。
如何用matplotlib和pandas自带的绘图函数轻松绘制柱状统计图形。

讨论

你之前做的数据分析工作中,遇到过需要从pdf文件抽取文本的任务吗?你是如何处理的?有没有更好的工具与方法?欢迎留言,把你的经验和思考分享给大家,我们一起交流讨论。

出处 https://blog.csdn.net/Stephen...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/44913.html

相关文章

  • 批量截取pdf文件

    摘要:能获取页面中文本的准确位置,以及字体或行等其他信息。安装修改的源码利用截取中的某几页,如果的中文字编码为编码,则无法解析。在简体中文操作系统中,编码代表编码。其一在文件中第行,改为此处是为了适应含有的编码的中文字符,提供对其的解码能力。 任务 现在我们有大量的pdf文件,我们想要截取每个文件中感兴趣的一部分,比如,我们下载了3500份上市公司的年度报告,我们想要找到包含关键审计事项部分...

    yzzz 评论0 收藏0
  • 爬虫 - 收藏集 - 掘金

    摘要:在这之前,还是有必要对一些概念超轻量级反爬虫方案后端掘金前言爬虫和反爬虫日益成为每家公司的标配系统。 爬虫修炼之道——从网页中提取结构化数据并保存(以爬取糗百文本板块所有糗事为例) - 后端 - 掘金欢迎大家关注我的专题:爬虫修炼之道 上篇 爬虫修炼之道——编写一个爬取多页面的网络爬虫主要讲解了如何使用python编写一个可以下载多页面的爬虫,如何将相对URL转为绝对URL,如何限速,...

    1fe1se 评论0 收藏0
  • 批量抓取网页pdf文件

    摘要:任务批量抓取网页文件有一个,里面有数千条指向下载链接的网页地址,现在,需要批量抓取这些网页地址中的文件。利用,具体逻辑是正常情况下,按次序下载文件,如果同一文件,下载失败次数超过,则跳过,下载下一个文件,并记录错误信息。 任务:批量抓取网页pdf文件 有一个excel,里面有数千条指向pdf下载链接的网页地址,现在,需要批量抓取这些网页地址中的pdf文件。python环境: anaco...

    pubdreamcc 评论0 收藏0
  • 批量抓取网页pdf文件

    摘要:任务批量抓取网页文件有一个,里面有数千条指向下载链接的网页地址,现在,需要批量抓取这些网页地址中的文件。利用,具体逻辑是正常情况下,按次序下载文件,如果同一文件,下载失败次数超过,则跳过,下载下一个文件,并记录错误信息。 任务:批量抓取网页pdf文件 有一个excel,里面有数千条指向pdf下载链接的网页地址,现在,需要批量抓取这些网页地址中的pdf文件。python环境: anaco...

    icyfire 评论0 收藏0
  • 一步步爬取Coursera课程资源

    摘要:至此登录功能初步实现。为了方便我们快速定位到每节课的所有资源,可以把一节课的所有资源文件均命名为课名文件类型。可以看一下一个测试例子中的文件,部分内容如下到这里为止,我们已经成功完成爬取课程资源的目标,具体的代码放在上。 原文地址 有时候我们需要把一些经典的东西收藏起来,时时回味,而Coursera上的一些课程无疑就是经典之作。Coursera中的大部分完结课程都提供了完整的配套教学资...

    Simon_Zhou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<