系统整理: python提取英文文献词频,并精准翻译!

项目简介:英文文献词频搞定三大步骤

一直以来,读透一篇英文文献并掌握其传递的核心思想一直是一件棘手的事情。相信饱受英文文献折磨的同学,也对于文献中出现的生僻词汇和专业词汇也十分困扰。本文从英文文献的词频的角度提供技术解决方案,主要包括三个主要的部分:

  1. 第一步,将英文文献由PDF格式转化成纯文本的格式;
  2. 第二步,对纯文本的英文文献进行清洗,并进行词频统计;
  3. 第三步,对统计的词频借助网络爬虫进行精准的翻译。

One: 英文文献PDF转成纯文本TXT格式

前期准备

运行程序版本:Python 3.7
集成开发环境:Pycharm 2019.3 Pro
安装pdfminer模块:

  • 注意,在Pycharm提供的第三方库中,有很多pdfminer库,本文使用的是pdfminer3k补充pdfminersix也可以进行PDF的转化,但是它与pdfminer3k中的某个文件发生冲突,请不要两个包放在一个环境中进行调用。

另外,可以通过pip直接安装pdfminer3k

pip install pdfminer3k

模块导入

1.导入sys模块,为了读取本地硬盘中,英文文献文件夹中的多个文件名称

import sys
import importlib
importlib.reload(sys)

2.导入pdfminer3k核心模块

from pdfminer.pdfparser import  PDFParser,PDFDocument
from pdfminer.pdfinterp import PDFResourceManager,PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal,LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed

3.构建解析函数parse()

def parse(text_path):
    """解析PDF文本,并保存到TXT文件中"""
    fp = open(text_path,'rb') #'rb'表示解读为二进制数据
    #用文件对象创建一个PDF文档分析器
    parer = PDFParser(fp)
    #创建一个PDF文档
    doc = PDFDocument()
    #连接分析器,与文档对象--也就说内容与载体连接
    parer.set_document(doc)
    doc.set_parser(parer)

    #提供初始化密码,如果没有密码,就创建一个空的字符串
    doc.initialize()

    #检测文档是否提供txt格式转化,不提供就忽略
    if not doc.is_extractable:
        raise PDFTextExtractionNotAllowed
    else:
        #创建PDF,资源管理器,来共享资源
        rsrcmgr = PDFResourceManager()
        #创建一个PDF设备对象
        laparams = LAParams()
        device = PDFPageAggregator(rsrcmgr,laparams=laparams)
        #创建一个PDF解释其对象
        interpreter = PDFPageInterpreter(rsrcmgr,device)

        #循环遍历列表,每次处理一个page内容
        #doc.get_pages() 获取pages列表
        for page in doc.get_pages():
            interpreter.process_page(page)
            #接受该页面的LTPage对象
            layout = device.get_result()
            #这里layout是一个LTpage对象,里面存放着这个page解析出的各种对象
            #一般包括LTTextBox,LTFigure,LTImage,LTTextHorizontal等等
            #想要获得文本就获得对象的text属性
            for x in layout:
                if(isinstance(x,LTTextBoxHorizontal)):
                    with open(r"prediction_text.txt",'a',encoding= 'utf-8') as f:
                        results = x.get_text()
                       # return results
                        f.write(results+'\n')

4.读取本地文件的所有英文文献的名称,并放在pdfs列表中

import glob
pdf_path = r'G:\pythonPjc\PDFminer3k_Project\document_translation'
pdfs = glob.glob("{}/*.pdf".format(pdf_path))

在这里插入图片描述
5.设置for循环,对列表中的PDF进行解析,并将解析失败的文件名称储存

list= []
for pdf in pdfs:
   # parse(pdf_path)
   print(pdf)
   try:
      parse(pdf)
   except:
      list.append(pdf)
with open(r"list_url.txt", 'a', encoding='utf-8') as f:
   # return results
   sep = ';'
   f.write(sep.join(list))

至此,英文文献PDF已经全部转成TXT纯文本格式

Two: 纯文本TXT格式的清洗与英文词频统计

模块导入

import sys, re,collections,nltk
from nltk.stem.wordnet import WordNetLemmatizer
from nltk.tokenize import word_tokenize
import xlwt

文本清洗

由于直接生成的英文纯文本文档格式比较杂乱,比如需要做一些缩写拆解,大小写还原,格式还原等一系列工作,比如

can’t 应该还原成 can not
I’ve 应该还原成 i have

故借助正则表达进行清洗,此部分参照公众号“数据Chocolate”(2019-06-23)的文章编写的正则规则。

# patterns that used to find or/and replace particular chars or words
# to find chars that are not a letter, a blank or a quotation
pat_letter = re.compile(r'[^a-zA-Z \']+')
# to find the 's following the pronouns. re.I is refers to ignore case
pat_is = re.compile("(it|he|she|that|this|there|here)(\'s)", re.I)
# to find the 's following the letters
pat_s = re.compile("(?<=[a-zA-Z])\'s")
# to find the ' following the words ending by s
pat_s2 = re.compile("(?<=s)\'s?")
# to find the abbreviation of not
pat_not = re.compile("(?<=[a-zA-Z])n\'t")
# to find the abbreviation of would
pat_would = re.compile("(?<=[a-zA-Z])\'d")
# to find the abbreviation of will
pat_will = re.compile("(?<=[a-zA-Z])\'ll")
# to find the abbreviation of am
pat_am = re.compile("(?<=[I|i])\'m")
# to find the abbreviation of are
pat_are = re.compile("(?<=[a-zA-Z])\'re")
# to find the abbreviation of have
pat_ve = re.compile("(?<=[a-zA-Z])\'ve")

词频统计

1.对词汇换行情况进行处理

由于在英文论文中常常出现一个单词换行的情况,导致有些词汇分裂,因此,在处理文本之前,对这种情况进行处理。处理的思路是:逐行读取纯文本文件,然后横向合并。借助正则表达式对词汇换行的情况进行处理。

def open_file(file_path):
    with open(file_path, encoding='utf-8') as f:
        # txt= f.read()
        txt0 = f.readlines()
        txt =[x.strip() for x in txt0]
        txt1 = " ".join(txt)
        txt2 = re.sub('(-\s)', '', txt1)
        return txt2

2.借助正则表达式,对缩写词汇进行替换

def replace_abbreviations(text):
    new_text = text
    new_text = pat_letter.sub(' ', text).strip().lower()
    new_text = pat_is.sub(r"\1 is", new_text)
    new_text = pat_s.sub("", new_text)
    new_text = pat_s2.sub("", new_text)
    new_text = pat_not.sub(" not", new_text)
    new_text = pat_would.sub(" would", new_text)
    new_text = pat_will.sub(" will", new_text)
    new_text = pat_am.sub(" am", new_text)
    new_text = pat_are.sub(" are", new_text)
    new_text = pat_ve.sub(" have", new_text)
    new_text = new_text.replace('\'', ' ')
    return new_text

3.对标点符号,以及文章中出现的大量的数字以及单个英文字符进行处理

def text_washing(text):
    new_text = re.sub('[,\.()":;!?@#$%^&*\d]|\'s|\'', '', text)  # txet wash
    new_text = re.sub("\W|[0-9]", " ", new_text)
    #deleting the solo character
    # 删掉单个字母
    txt4 = new_text.split(" ")
    list = []
    for i in txt4:
        i = i.strip()
        if len(i) > 2:
            list.append(i)
    wash_text = " ".join(list)
    return wash_text

4.对单词的词性进行还原,并借助停用词词典,对停用词进行剔除

def merge(text):
    words = text.split()
    new_words = []
    for word in words:
        if word:
            tag = nltk.pos_tag(word_tokenize(word)) # tag is like [('bigger', 'JJR')]
            pos = get_wordnet_pos(tag[0][1])
            if pos:
                lemmatized_word = lmtzr.lemmatize(word, pos)
                new_words.append(lemmatized_word)
            else:
                new_words.append(word)
    stopwords = [word.strip().lower() for word in open("stopwords.txt")]
    clean_tokens = [tok for tok in new_words if len(tok) > 1 and (tok not in stopwords)]
    return clean_tokens


def get_wordnet_pos(treebank_tag):
    if treebank_tag.startswith('J'):
        return nltk.corpus.wordnet.ADJ
    elif treebank_tag.startswith('V'):
        return nltk.corpus.wordnet.VERB
    elif treebank_tag.startswith('N'):
        return nltk.corpus.wordnet.NOUN
    elif treebank_tag.startswith('R'):
        return nltk.corpus.wordnet.ADV
    else:
        return ''

5.构建词频的统计函数

def append_ext(words_list):
    count = collections.Counter(words_list)
    words =count.most_common()
    new_words = []
    for item in words:
        word, count = item
        tag = nltk.pos_tag(word_tokenize(word))[0][1] # tag is like [('bigger', 'JJR')]
        new_words.append((word, count, tag))
    return new_words

6.将数据写入文件

def data_write(file_path, datas):
    f = xlwt.Workbook()
    sheet1 = f.add_sheet(u'sheet1', cell_overwrite_ok=True)  # 创建sheet
    # 将数据写入第 i 行,第 j 列
    j = 2
    for data in datas:
        for i in range(len(data)):
            sheet1.write(i, j, data[j])
        i = i + 1
    f.save(file_path)  # 保存文件

至此,我们将纯文本中的词汇进行了清洗和词频统计,效果图如下
在这里插入图片描述

Three: 对英文词频进行精准翻译

模块导入

本部分主要借助urllib模块编写爬虫程序

from openpyxl import load_workbook
from openpyxl import Workbook
import json
import sys
from urllib.parse import urlparse, quote, urlencode, unquote
from urllib.request import urlopen
import re
import time

词汇翻译解析函数构建

调用有道翻译url,对词汇进行翻译。注意,经测试,有道翻译页面设置反爬虫机制,当抓取速度过快或者单位时间内抓取数量过多时,网页便拒绝访问。一个好的解决方案是,访问延迟,经验表明以3秒为时间间隔 比较合适。

def fetch(query_str):
    query = {"q": "".join(query_str)}  # list --> str: "".join(list)
    # print(query)
    url = 'https://fanyi.youdao.com/openapi.do?keyfrom=11pegasus11&key=273646050&type=data&doctype=json&version=1.1&' + urlencode(
        query)
    time.sleep(3)
    response = urlopen(url, timeout=3)
    html = response.read().decode('utf-8')
    return html

HTML解析函数的构建

def parse(html, num):
    d = json.loads(html)
    try:
        if d.get('errorCode') == 0:
            explains = d.get('basic').get('explains')
            result = str(explains).replace('\'', "").replace('[', "").replace(']', "")  # .replace真好用~
            sheet.cell(row=num, column=2).value = result
            num = num + 1
            for i in explains:
                print(i)
        else:
            print('无法翻译!****')
            sheet.cell(row=num, column=2).value = ' '  # 若无法翻译,则空出来
            num = num + 1
    except:
        print('****翻译出错!')  # 若无法翻译,则空出来
        sheet.cell(row=num, column=2).value = ' '
        num = num + 1

词汇翻译主函数

def main():
    Sheet1 = ExcelFile['Sheet1'];
    num = 1
    while (1):
        word = Sheet1.cell(row=num + 2, column=1).value
        if (word != None):
            print('正在翻译第', end='');
            print(num, end='');
            print('个单词')
            print(word)
            try:
                parse(fetch(str(word)), num)
            except:
                continue
            num += 1
            print()
            out.save('out.xlsx')
        else:
            print('翻译结束!')
            break
    ExcelFile.close()
    # out.save('word.xlsx')

至此,我们的全部工作已经完成,让我们看一下效果图吧!

在这里插入图片描述
参考资料
[1] 自然语言处理 | NLTK英文分词尝试
[2] Python使用pdfminer解析PDF
[3] Python 3.6 中使用pdfminer解析pdf文件

  • 19
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
下面是一个统计文本文件单词出现频率的 Python 代码: ```python def word_count(file_path): with open(file_path, 'r') as f: words = f.read().split() word_count = {} for word in words: if word not in word_count: word_count[word] = 1 else: word_count[word] += 1 return word_count file_path = 'example.txt' word_count_dict = word_count(file_path) print(word_count_dict) ``` 这个代码实现了以下功能: 1. 定义了一个函数 `word_count`,它接收一个文件路径作为参数。 2. 打开文件,并将文件内容读入字符串变量 `words` 。 3. 定义一个空字典 `word_count`,用于存储单词及其出现的次数。 4. 遍历 `words`,对于每个单词,如果它不在 `word_count` ,就将它加入字典并将值设为 1;否则就将它对应的值加 1。 5. 返回 `word_count` 字典。 6. 调用 `word_count` 函数,并将返回值存储在 `word_count_dict` 变量。 7. 打印 `word_count_dict`。 这个代码的主要思路是将文件的所有单词存储到一个字典,字典的键是单词,值是该单词出现的次数。在遍历文件的单词时,对于每个单词,如果它已经在字典出现过,就将对应的值加 1,否则就将它加入字典并将值设为 1。最终,字典存储的就是文件每个单词出现的次数了。 需要注意的是,这个例子只是一个简单的统计单词出现频率的示例,它并没有考虑到单词的大小写、标点符号等问题。如果需要更精确地统计单词出现频率,还需要对单词进行一些预处理(比如将所有单词转换为小写),以及去除标点符号等干扰因素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值