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

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

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

## 0. 論文pdfを収集。 
　Google Scholarとかから拾ってくる。

## 1. 各pdfをそれぞれtxtに変換。
　ターミナルでpdfminer.sixをインストール（入っていなければ）

```
$ pip install pdfminer.six
```
```python:各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を１つにまとめる。
```python:作った各txtを１つにまとめる。
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を１つにまとめる。
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内の各単語の登場回数を調べる。
```python: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
```
```python: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に変換。  
 - 大量のPDFファイルを、pdfminerを使ってtextファイルに変換する  
https://qiita.com/monchy-monchy/items/85ded85423be6108f05b  
 - PDFMinerでPDFから日本語テキストを抽出する  
https://qiita.com/korkewriya/items/72de38fc506ab37b4f2d
2. 作った各txtを１つにまとめる。  
 - 同上
3. txt内の各単語の登場回数を調べる。  
 - 英単語帳作成～その2～  
http://kuroyagi.hatenablog.com/entry/2017/10/07/202830
4. Mac内蔵辞書を使って単語帳（登場回数順）の作成。  
 - Python Tips： Mac の辞書アプリを Python から利用したい  
https://www.lifewithpython.com/2016/07/python-use-mac-dictionary-app.html