内容提要:
- 提取pdf中的英文单词,保存到txt中,导入背单词app里学习!
- 前提准备
- 背景
- 代码设计
- 功能实现
- 解析PDF文件,提取所有内容
- 筛选PDF内容,提取所有单词
- 将单词按照词频高低排序
- 将排序结果根据传入的size数量进行拆分保存
- 编写入口函数
- 启动
- 单元测试代码
- 扩展内容
- 将单词文件导入背单词APP中
- 参考资料
前提准备
背景
当你拿到一本英文的技术文档(PDF),里面大部分单词都不认识的时候。很有可能你就会需要一个能够提取PDF文档中所有英文单词,按照单词出现的频率由高到低排列,再将排列的单词加入某款背单词APP中!这样你就可以用碎片化时间学习一些一定能用到的英文单词了!
代码设计
背景描述了大致需求,下面确定本次需要实现以下功能:
- 解析PDF文件,提取所有内容
- 筛选PDF内容,提取所有单词
- 将单词按照词频高低排序
- 将排序结果根据传入的size数量进行拆分保存
开发环境:
- Python3.8.2
- Pycharm
- pdfminer3k
功能实现
解析PDF文件,提取所有内容
解析PDF使用到第三方库PDFMiner3K,用于把PDF读成字符串。
from pdfminer.pdfinterp import PDFResourceManager,process_pdf
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from io import StringIO
def readPDF(pdffile):
rsrcmgr = PDFResourceManager()
retstr = StringIO()
laparams = LAParams()
device = TextConverter(rsrcmgr,retstr,laparams=laparams)
process_pdf(rsrcmgr,device,pdffile)
device.close()
content = retstr.getvalue()
retstr.close()
return content
筛选PDF内容,提取所有单词
将获取到的content通过正则分割为list对象,再使用列表推导式把所有单词转换为小写。
import re
def pdf_to_wordlist(pdfPath):
# 获取pdf的内容
pdffile = open(pdfPath, "rb")
content = readPDF(pdffile)
# 将pdf转换为单词list
content = content.replace('\n',',')
line_word = re.split(r'\W', content)
word_list = [word.lower() for word in line_word if word and word.isalpha() ]
将单词按照词频高低排序
引入collections的Counter对词频进行统计,多次转换后获得一个词频由高到低的list。
from collections import Counter
# 按照词频从高到低排序
result = Counter(word_list)
r = [(v,k) for k,v in result.items()]
r = sorted(r,reverse=True) # 有词频数量
sort_word_list = []
for v,k in r:
sort_word_list.append(k)
将排序结果根据传入的size数量进行拆分保存
按照指定size切割list,将每个切割后的list放入一个大的list中。
def split_list(list, n,newList=[]):
if len(list)<=n:
newList.append(list)
return newList
else:
newList.append(list[:n])
return split_list(list[n:],n)
# 调用:
# split_list(['a','b','c'], 2)
# 返回:
# [['a','b'],['c']]
将排序后的单词list,根据size写入文件。
def save_word(saveWordPath,list,size=0):
# 按照size拆分list
result_list = split_list(list, size)
num = 1 # 第num个文件
for single_list in result_list:
savePath = saveWordPath.replace('.txt','_'+str(num)+'.txt')
with open(savePath, 'w', encoding='utf8') as f:
single_list= '\n'.join(single_list)
f.writelines(single_list)
num += 1
编写入口函数
编写main函数将前面每个功能串起来,这样只需要调用一个入口函数就能实现功能。入口函数中指定pdf文件位置和result文件位置。
# 传参pdf名称,结果文件拆分大小即可。
def extract_main(pdfFileName,size):
pdfPath = "pdf/"+pdfFileName
# 提取pdf中的单词并按词频排序
word_list = pdf_to_wordlist(pdfPath)
# 保存为单词
saveWordPath = pdfPath.replace('pdf/','result/').replace('.pdf','.txt')
save_word(saveWordPath,word_list,size)
启动
这里可以使用线程来启动,避免在解析大文件时等待太久。(后续集成到web后,可以先写入一条记录,等执行完毕后再回写记录状态)
if __name__ == '__main__':
t = threading.Thread(target=extract_main, args=('django_test.pdf',20,))
t.start()
print('任务已提交')
单元测试代码
开发视角确实不想写单元测试代码……后续集成到web时再补上。
扩展内容
将单词文件导入背单词APP中
网上找了几款支持自定义词库的背单词APP,下载了几个,有些现在已经不支持导入功能了。亲身体验之火,最终推荐大家使用“不背单词”APP。
(下面图片是我把django官方英文文档的单词提取出来,导入自定义词书里。。确实好用!)
参考资料
,Python读取PDF内容,2016-05-24,fullerhua