LoginSignup
23
21

More than 5 years have passed since last update.

英語論文から単語を抽出&登場回数順にソートし、さらに意味も載った単語帳まで作ってみた。

Last updated at Posted at 2019-02-14

はじめに

 英語論文を読み始めの頃、知らない単語、特に専門単語が多すぎてつまづくことがよくある。紙へ新出単語をリストアップしていくのも悪くはない。しかし、これをPythonにやらせたら楽になるのではないか、と思い表題のことをやってみた。今回は専門用語の意味を調べるところまでは行かなかったが、一般的な単語の意味を調べるところまではできた。
 ipynbファイルは、ここに置いた。ダウンロードの仕方が分からない方はここをクリックするとzipファイルがダウンロードされる。

目次

0.論文pdfを収集。
1. 各pdfをそれぞれtxtに変換。
2. 作った各txtを1つにまとめる。
3. txt内の各単語の登場回数を調べる。
4. Mac内蔵辞書を使って単語帳(登場回数順)の作成。

0. 論文pdfを収集。

 Google Scholarとかから拾ってくる。

1. 各pdfをそれぞれtxtに変換。

 ターミナルでpdfminer.sixをインストール(入っていなければ)

$ pip install pdfminer.six
各pdfをそれぞれtxtに変換。
import os
import re
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from io import StringIO

pdf_folder_path = os.getcwd() + '/' + 'pdf' # 現在のフォルダのパスを取得
text_folder_path = os.getcwd() + '/' + 'text' # pathの表記がmac仕様。windowsの場合は、'/'を'\'に修正する。

os.makedirs(text_folder_path, exist_ok=True)
pdf_file_name = os.listdir(pdf_folder_path)

# nameがpdf(末尾が.pdf)の場合はTrue、それ以外はFalseを返す関数
def pdf_checker(name):
    pdf_regex = re.compile(r'.+\.pdf')
    if pdf_regex.search(str(name)):
        return True
    else:
        return False

# pdfをtxtに変換する関数(ここについて僕はあんまりわかりません)
# https://qiita.com/korkewriya/items/72de38fc506ab37b4f2d より
def convert_pdf_to_txt(name, txtname, buf=True):
    rsrcmgr = PDFResourceManager()
    if buf:
        outfp = StringIO()
    else:
        outfp = file(txtname, 'w')
    codec = 'utf-8'
    laparams = LAParams()
    laparams.detect_vertical = True
    device = TextConverter(rsrcmgr, outfp, codec=codec, laparams=laparams)

    fp = open(pdf_folder_path + '/' + name, 'rb') # nameを開く。
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    for page in PDFPage.get_pages(fp):
        interpreter.process_page(page)
    fp.close()
    device.close()
    if buf:
        text = outfp.getvalue()
        make_new_text_file = open(text_folder_path + '/' + name + '.txt', 'w') # name.txtを開く。
        make_new_text_file.write(text)
        make_new_text_file.close()
    outfp.close()

# 各pdfをそれぞれtxtに変換。
for name in pdf_file_name:
    if pdf_checker(name):
        convert_pdf_to_txt(name, name + '.txt')  # pdf_checkerを使い、True(末尾が.pdfの場合)は変換に進む。
    else:
        pass                                    # pdfファイルでない場合にはpass

2. 作った各txtを1つにまとめる。

作った各txtを1つにまとめる。
txt_file_name = os.listdir(text_folder_path)
mer = open('data.txt', 'w', encoding='UTF-8', newline='') # data.txtを新規作成(初期化)
mer.close()

# nameがtxt(末尾が.txt)の場合はTrue、それ以外はFalseを返す関数
def txt_checker(name):
    txt_regex = re.compile(r'.+\.txt')
    if txt_regex.search(str(name)):
        return True
    else:
        return False

# txtをマージ(統合)する関数
def txt_merge(name):
    f = open(name, 'r', encoding='UTF-8', newline='')
    mer = open('data.txt', 'a', encoding='UTF-8', newline='')
    mer.write(f.read())
    f.close()
    mer.close()

# 各txtを1つにまとめる。
for name in txt_file_name:
    if txt_checker(name):
        txt_merge(text_folder_path + '/' + name)     # txt_checkerを使い、True(末尾が.txtの場合)は変換に進む。
    else:
        pass                                         # txtファイルでない場合にはpass

3. txt内の各単語の登場回数を調べる。

txt内の各単語の登場回数を調べる。
from collections import Counter
import csv

f = open('data.txt', 'r', encoding='UTF-8') # 作ったdata.txtを読み込む。
target_text = f.read()
f.close()

# 各単語の登場回数を調べる。
words = re.split(r'\s|\,|\.|\(|\)', target_text.lower())
counter = Counter(words)

4. Mac内蔵辞書を使って単語帳(登場回数順)の作成。

 ターミナルでPyObjCをインストール(入っていなければ)

$ pip3 install pyobjc
Mac内蔵辞書を使って単語帳(登場回数順)の作成。
from DictionaryServices import DCSGetTermRangeInString, DCSCopyTextDefinition

# 既に知っている単語のリストを作成
alreadyknown = ["the","of","and","in","to","is","for","that","by","this","as","are","be","on","with"\
                ,"from","an","which"]

f = open('data.csv', 'w', encoding='UTF-8', newline='') # data.csvを新規作成(初期化)
csvwriter = csv.writer(f)
label = ['wordlist', 'count', 'definition']
csvwriter.writerow(label)
f.close()

# Mac内蔵辞書でwordの意味を調べ、辞書に有ればその定義を返し、辞書に無い場合は'Not Found'を返す関数
def word_def(word):
    try:
        word_range = DCSGetTermRangeInString(None, word, 0)
        return DCSCopyTextDefinition(None, word, word_range)
    except IndexError:
        return 'Not Found'

# 単語帳(登場回数順)の作成。
for word, count in counter.most_common():
    csvlist = [] # csvlistを初期化
    if len(word) < 2 or word in alreadyknown or count < 2: 
        # 一文字の単語、既に知っている単語(リストalreadyknownにある)、登場回数が一回しかないなら飛ばす。
        pass
    else:
        csvlist.append(word)           # 1列目は単語名
        csvlist.append(count)          # 2列目は単語の登場回数
        csvlist.append(word_def(word)) # 3列目は単語の意味
        f = open('data.csv', 'a', encoding='UTF-8', newline='')
        csvwriter = csv.writer(f)    
        csvwriter.writerow(csvlist) # csvlistを末尾へ追加
        f.close()

改善点など

  • 数字や記号、意味をなさない文字列を省くのが難しい。
  • 特に専門用語だと意味が内蔵辞書に載ってない。Wikipediaからスクレイピングして取って来れば良いのかもしれない。スクレイピングのマナーに精通してないため、怖くてまだ試していない。後で気が向いたら別の記事で投稿しようと思う。
  • 単語の意味が見にくいのも改善の余地あり。

参考サイト

  1. 各pdfをそれぞれtxtに変換。
  2. 作った各txtを1つにまとめる。
    • 同上
  3. txt内の各単語の登場回数を調べる。
  4. Mac内蔵辞書を使って単語帳(登場回数順)の作成。
23
21
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
21