心理学作业的命令行小工具

原创文章,转载请注明出处并留言

用途

把目标文件夹中所有的pdf找到,并提取出它们的报纸名称,六个关键词是否在文章中出现,以excel表格记录保存,并将pdf全部转换为txt格式保存在一个新的文件夹中。

使用方法:在命令行中输入python miner.py 你的pdf存放的文件夹
(前提:安装python2.7以上&3.0一下版本,安装pdfminer xlwt模块)

安装扩展模块小贴士:去python官网,点击PyPi,查找相应模块,根据自己的py版本下载压缩包,解压后在命令行中cd到解压后的文件目录,输入 python setup.py install 看到最后successful之后即说明模块安装成功(之前用pip安装模块总会报错,所以只能用最原始的方法)。一般这些模块都在github上有一个库,作者们都支持大家一起完善,可以提交你的版本呢。

分析一下pdfminer模块

事实证明,考虑事情太片面是要付出代价的。刚开始使用pdfminer时,就因为我处理的pdf文件有错误,输出的一直是(cid:3240)这样的怪东西,我查来查去也无果,后来换了一个pdf,居然成功了…不过也因此了解了下各种编码,unicode两字节,utf-8是它的压缩改良版本,gb2312,gbk常用中文编码,ascii真心烦人,最无语的是命令行是cp936编码,python编码就够渣了,碰上命令行真是冤家路窄,不过好在编码可以各种互转。

下面进入正题:https://euske.github.io/pdfminer/

(安装时一定要注意添加CJK支持,不然含有中文的pdf不能提取,这在上面的网页里有说明)

这个模块的主要功能是:解析和分析pdf,提取文字图片布局等信息,可以将pdf转换为几种格式的文件输出

下面大概看看各个文件(都是解压后的文件夹中的):

  • setup.py没什么可说的
  • cmaprsrc里面有4个长长的txt,这些是Adobe官网给出的标准CID与unicode互转方法(你会发现就是CJK这三种格格不入的语言)
  • pdfminer中的cmapdb.py就是利用这四个txt生成一大堆cmap里的pickle.gz,毕竟pickle是python专用的数据格式,而且每个txt里面都是多种编码混合在一起,把每一种分别以pickle格式保存有利于使用
  • tools里面有一些命令行小工具我只了解其中几个,conv_cmap.py就是可以将上面所说的txt中的编码转换提取出来,存在pickle里pdf2txt.py可以将pdf转成txt,html,xml,tag格式,还有一个没用过,但是顾名思义,latin2ascii,将拉丁文编码的转成ascii的
  • build里面就是拷贝到python安装目录下的Scripts和tools里面的内容,没什么可说的

程序

思路

  1. 读取命令行参数
  2. 获取待处理的pdf文件列表
  3. 将每个pdf转为txt
  4. 查找txt中的报刊名称和各关键词是否出现
  5. 将结果依次输出至excel中并保存

实现

由于所有操作在main函数中执行,为了保证某些变量的全局性,我在main函数中嵌套定义了process函数用于处理每一个pdf。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  def process(data):
debug = 0
# input option default
password = ''
pagenos = set()
maxpages = 0
# output option default
outfile = root+'\\'+data+'.txt'
imagewriter = None
rotation = 0
codec = 'utf-8'
caching = True
laparams = LAParams()
PDFDocument.debug = debug
PDFParser.debug = debug
CMapDB.debug = debug
PDFPageInterpreter.debug = debug
rsrcmgr = PDFResourceManager(caching=caching)
outfp = file(outfile,'w')
device = TextConverter(rsrcmgr, outfp, codec=codec, laparams=laparams,imagewriter=imagewriter)
fp = file(data+'.pdf', 'rb')
#检测pdf是否可以抽取文本,若不可以,直接返回
fp_parser = PDFParser(fp)
doc = PDFDocument(fp_parser)
if not doc.is_extractable:
return
print 'Reading ...'+data+'.pdf....'
interpreter = PDFPageInterpreter(rsrcmgr, device)
for page in PDFPage.get_pages(fp, pagenos,maxpages=maxpages, password=password,caching=caching, check_extractable=True):
page.rotate = (page.rotate+rotation) % 360
interpreter.process_page(page) # pdf转换为txt
fp.close()
device.close()
outfp.close()
fo = codecs.open(outfile, 'r', 'utf-8')
#向excel表格里填写数据
tmp = fo.read()
pos = tmp.find('/')
if pos != -1:
ws.write(i+1,1,tmp[:pos].strip()) #ws是main函数中的变量(excel中创建的表格)
for j in range(len(wd)):
if tmp.find(wd[j]) != -1:
ws.write(i+1,j+3,1)
else:
ws.write(i+1,j+3,0)
fo.close()

main函数中包括对参数的判定和是否含有pdf文件等的一些处理,创建excel表格,填写表格内容,完整代码请见我的github: https://github.com/TombRaiderjf/TombRaiderjf.github.io/blob/master/documents/miner.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 在当前目录创建excel表格 
w = xlwt.Workbook(encoding='utf-8')
style = xlwt.XFStyle()
font = xlwt.Font()
font.name = 'SimSun'
style.font = font
ws = w.add_sheet('Sheet1')
# 填写表头
wd =[ u'医患冲突', u'医疗纠纷', u'医疗事故',u'医疗暴力', u'医闹' , u'暴力伤医']
ws.write(0,0,'编号')
ws.write(0,1,'报刊')
ws.write(0,2,'日期')
for pt in range(len(wd)):
ws.write(0,pt+3,wd[pt])

效果

Thanks!