Pythonは、豊富なライブラリを扱えることからデータ解析の分野で人気があります。
今回はPythonで複数のライブラリを使用し、英語論文のPDFファイルからテキストを抽出後に翻訳してWordファイルに自動で出力するコードを作成しました。
Pythonを入れてなくても使えるEXEファイルも作ってみました → ダウンロード
ソースコードは以下の通りです。6行目に翻訳したい英語論文のファイル名を入れて実行すると、自動的に英語論文が翻訳されてWordで出力されます。
さらに、このソースコードの内容について、どのようなプロセス処理を行っているかを細かく分けて解説していきます。
Pythonのインストール方法はこちら
Pythonのインストールと開発環境(PyCharm)の導入方法を解説
from googletrans import Translator import PyPDF2 import time import docx import os FILE = "pump.pdf" text = "" with open(FILE, mode="rb") as pdf_file: reader = PyPDF2.PdfFileReader(pdf_file) for i in range(reader.getNumPages()): text += reader.getPage(i).extractText() with open("pdf_text.txt", "w", encoding="utf-8") as pdf_text: pdf_text.write(text) emp = " " with open("pdf_text.txt", "r", encoding="utf-8") as pdf_text: with open("convert_text.txt", "w", encoding="utf-8") as convert_text: for line in pdf_text: pdf_text = line.replace("\n", "") pdf_text = pdf_text.replace("fig.", "fig").replace("Fig.", "Fig") pdf_text = pdf_text.replace(".", ".\n") for i in range(1, 7): pdf_text = pdf_text.replace(emp * i, " ") convert_text.write(pdf_text) transtext = "" translated_text = "" with open("convert_text.txt", "r", encoding="utf-8") as convert_text: for lina in convert_text: transtext += convert_text.readline() if len(transtext) > 4000: print(str(len(transtext))) translated_text += Translator().translate(transtext, dest="ja").text transtext = "" time.sleep(3) translated_text += Translator().translate(transtext, dest="ja").text print(str(len(transtext))) doc = docx.Document() doc.add_paragraph(translated_text) doc.save("pdf_translated_ja.docx") os.remove("pdf_text.txt") os.remove("convert_text.txt")
ライブラリのインストール
今回使用するライブラリは以下の3種類です。
- PyPDF2
- googeletrans
- docx
「PyPDF2」はPDF操作、「googletrans」はGoogle翻訳、「docx」はWordの操作を行います。
コマンドプロンプトで「pip install PyPDF2」、「pip install googletrans」、「pip install python-docx」と入力してそれぞれインストールします。
PDFを読み込む
import PyPDF2 FILE = "pump.pdf" text = "" with open(FILE, mode="rb") as pdf_file: reader = PyPDF2.PdfFileReader(pdf_file) for i in range(reader.getNumPages()): text += reader.getPage(i).extractText() with open("pdf_text.txt", "w", encoding="utf-8") as pdf_text: pdf_text.write(text)
PyPDF2モジュールを使ってPDFファイルの読み込みを行います。「PyPDF2.PdfFileReader(“任意のファイル名.pdf”)」でPDFを読み込んで「reader」に格納しています。「reader」の中身がどうなっているかというと、
print(reader) の実行結果
<PyPDF2.pdf.PdfFileReader object at 0x0000000003484400>
読み込んだPDFファイルを識別するidのようなものです。これを用いてPDFファイルから色々な情報を引き出していきます。
「getPage(任意の数字)」は「reader」から任意のページの情報を引き出します。
print(reader.getPage(0)) の実行結果
{‘/Type’: ‘/Page’, ‘/Parent’: IndirectObject(2, 0), ‘/Resources’: {‘/Font’: {‘/F1’: IndirectObject(5, 0), ‘/F2’: IndirectObject(7, 0), ‘/F3’: IndirectObject(9, 0), ‘/F4’: IndirectObject(11, 0)}, ‘/ProcSet’: [‘/PDF’, ‘/Text’, ‘/ImageB’, ‘/ImageC’, ‘/ImageI’]}, ‘/MediaBox’: [0, 0, 595.2, 841.92], ‘/Contents’: IndirectObject(4, 0), ‘/Group’: {‘/Type’: ‘/Group’, ‘/S’: ‘/Transparency’, ‘/CS’: ‘/DeviceRGB’}, ‘/Tabs’: ‘/S’, ‘/StructParents’: 0}
ここから「extractText()」でPDFファイル内のテキストを取得することができます。「reader.getPage(0).extractText()」のように書くと、1ページ目のテキストを読み取れるということです。これで全ページのテキストを読み取るために、for文で繰り返し行います。
for文で最後のページまで繰り返すために、「getNumPages()」でPDFの総ページ数を取得しています。これで1ページごとに読み込んだテキストを「text」に次々に足していけば、PDFからの全テキスト読み取りが完了です。
ここでは、1度読み取ったテキストを「.txt」で出力します。出力の際にはそのままだとエラーが出るので、文字コードを「utf-8」にエンコードしています。
テキストを整形する
英語論文のほとんどは、テキストに変換しても改行の位置がおかしかったり、ピリオドが図の説明で「Fig.」みたいになっている場合が多いです。そのため、Google翻訳の時に誤訳したり、単純に読みづらかったりと色々問題があります。
それを避けるために、読み取ったテキストを整形してある程度きれいにします。
emp = " " with open("pdf_text.txt", "r", encoding="utf-8") as pdf_text: with open("convert_text.txt", "w", encoding="utf-8") as convert_text: for line in pdf_text: pdf_text = line.replace("\n", "") pdf_text = pdf_text.replace("fig.", "fig").replace("Fig.", "Fig") pdf_text = pdf_text.replace(".", ".\n") for i in range(1, 7): pdf_text = pdf_text.replace(emp * i, " ") convert_text.write(pdf_text)
先ほど出力した「pdf_text.txt」を開き、後の書き込み用に「covert_text.txt」を新たに開いています。
「for line in pdf_text:」のように書くことで、「pdf_text」に対して1行ずつfor文の処理を実行することが出来ます。これと「replace」を使って、文字の置換でテキストの整形をしていきます。
「pdf_text = line.replace(“\n”, “”)」では、改行コードである「\n」を無に置き換えてテキスト内の改行を全て消しています。これをしないと、例えば「article」が改行によって「art」と「icle」の2つに分かれていて、Google翻訳にかけても意味わからない日本語訳になったりします。
そのため、改行を一度全て消して単語がきちんと繋がるようにしておきます。
次の「pdf_text = pdf_text.replace(“fig.”, “fig”).replace(“Fig.”, “Fig”)」で、図の説明に使う「fig.」や「Fig.」のピリオドを取り除きます。翻訳の時に邪魔なので。
「pdf_text = pdf_text.replace(“.”, “.\n”)」は、ピリオドを「.\n」に置換することで文の終わりで改行するようにしています。
英語論文の内容によっては、ピリオドの後に半角スペースを入れることで「6.5」のように文末以外でピリオドが入っているところをある程度無視できます。ただし、文末のピリオドの後に半角スペースを使っている場合に限ります。
「pdf_text = pdf_text.replace(emp*i, ” “)」では余分な半角スペースを取り除きます。論文によっては英単語の間に2個以上半角スペースが入っている部分があることも少なくないので、見た目をきれいにするために入れました。
for文で7連続までの半角スペースは除去するようにしていますが、たまに消えないところがあります。とはいえGoogle翻訳にほぼ影響はないので消さなくても特に問題はないです。
最後に「.txt」で出力します。これで文章がきれいな形になっているのが確認できます。
テキストを翻訳する
テキストの整形も済み準備が完了したので、いよいよ翻訳します。Google翻訳はウェブサービスなので操作が面倒かと思いきや、専用のライブラリがあるので簡単です。
from googletrans import Translator import time transtext = "" translated_text = "" with open("convert_text.txt", "r", encoding="utf-8") as convert_text: for lina in convert_text: transtext += convert_text.readline() if len(transtext) &amp;gt; 4000: print(str(len(transtext))) translated_text += Translator().translate(transtext, dest="ja").text transtext = "" time.sleep(3) translated_text += Translator().translate(transtext, dest="ja").text print(str(len(transtext)))
例のごとくテキストを読み込みます。今度は、先ほどテキスト整形を行い出力した「convert_text.txt」です。
翻訳はgoogletransを使って「Translator().translate(“任意の文字列”, src=”翻訳元の言語”, dest=”翻訳先の言語”)」のように書くことでできます。言語入力は、「en」で英語、「ja」で日本語です。例としてdogを翻訳すると、以下のようになります。
print(Translator().translate(“dog”, src=”en”, dest=”ja”)) の出力結果
Translated(src=en, dest=ja, text=犬, pronunciation=Inu, extra_data=”{‘translat…”)
そのままだとテキスト以外の情報も入っているので、「Translator().translate(line, dest=”ja”).text」で翻訳結果のテキストだけを取り出します。
Google翻訳は一度に処理できる文字数が5000なので、それ以内に収まるように文章を取り出して翻訳しないといけません。そのため、一回で翻訳が終わらない場合は複数回に分けて翻訳します。
まず、「transtext」に「readline()」で1行ずつ文章を追加していき、「len()」で文字数を計算して4000文字以上になったらまとめて翻訳を行います。翻訳が完了したら「translated_text」に翻訳済みの文章を追加し、「transtext」の中身をリセットして繰り返します。
ここでは翻訳が終わった直後に3秒間停止するようにsleep()を入れています。Google翻訳に高速でリクエストを送ると、負荷がかかって迷惑になる可能性があるので、処理ごとに時間を空けるようにしておきましょう。
Wordに書き込みと出力をする
最後に、Wordへの出力と、必要なくなったテキストファイルの削除を行います。
import docx import os doc = docx.Document() doc.add_paragraph(translated_text) doc.save("pdf_translated_ja.docx") os.remove("pdf_text.txt") os.remove("convert_text.txt")
Wordファイルの操作もライブラリを使ってできるので簡単です。
「docx.Document()」で新規のWordファイルを開いた後、「add_paragraph(“任意の文字列”)」で文字を入力します。操作をしたWordファイルは、「save(“任意の文字列”)」で保存することができます。Wordファイルの操作は以上です。
最後に、os.remove(“ファイル名”)で、Wordで翻訳したテキストを出力するまでのプロセスで出力したテキストファイルを削除します。
削除するのは「pdf_text.txt」と「convert_txt」の2つです。
以上でソースコードの解説は終わりです。
一応翻訳機能の実装は出来たものの、論文のフォーマットが一律じゃないのでうまくテキストを整形するのが難しいです。タイトルやページ、参考文献、表がうまく操作できない他、そもそもPDFで読み込んだ時点で単語と単語の間に半角スペースがなかったりと色々不具合が多いです。(半角スペースがない件はGoogle翻訳がなんとかしてくれますが)
とはいえ翻訳作業自体はそれなりに楽できそうなので、ひとまず安心です。ソースコードの方はこれから少しずつブラッシュアップしていこうと思います。
Pythonに関する他の記事
Pythonでブラウザを自動操作する2つの方法を解説