1. 概要
誰でもこんな経験したことあると思います.
- DeepLで翻訳しながら英語の論文を読む
- 面倒になりPDFごといい感じに翻訳してくれるサービスを探す
- どのサービスもフォーマットが崩れたり,少しずつしかできなかったりで微妙
- 結局翻訳したい部分をDeepLにコピペで翻訳してもらう(2~4を無限ループ)
DeepLへのコピペもPDFの端で改行されてしまい,おかしな翻訳になることもしばしば.ということで,
今回の目標は,英文をコピーしたはずがいつの間にか和文になってる!!
です.
2. 本編
今回はこんな流れで進めていきます.
2-1. クリップボードのコピーを監視
クリップボード関連はpyperclipというライブラリを使えば簡単に操作できます.
pyperclipについては以下のサイトを参考にしました.
Python, pyperclipでクリップボードを操作(コピー、ペースト、監視)
まずはpipでインストール.
pip install pyperclip
waitForNewPasteメソッドを使えばクリップボードの更新を監視することができます.また,引数に待機時間を設定することができます.以下の実装だと300秒(5分間)クリップボードの更新がなかったらプログラムが終了するようになっています.
import pyperclip
while True:
try:
# コピーされた英文のテキスト
text = pyperclip.waitForNewPaste(300)
except pyperclip.PyperclipException:
print("5分間入力がないため終了します")
break
except KeyboardInterrupt:
print("終了します")
break
2-2. 改行やスペースなどをいい感じに整える
コピーした英文をそのままDeepLにつっこむと,PDFの端で改行されていたり,文中の数式で不自然な改行が入っていたりします.
改行をスペースにするだけなら,
text.replace("\n", " ")
とするだけでいいのですが,本当に改行している部分では改行したままにしておきたいです.
ということで,改行後の一文字目が大文字かそれ以外かで判断することにしました.具体的には,改行後の一文字目が大文字ならそのまま,それ以外なら改行をスペースに置換するという処理を行いました.
import re
# 改行のインデックスを取得
new_line_list = [i.start() for i in re.finditer("\n", text)]
# 改行後に大文字以外があるかどうか
replace_index = []
# 改行後に大文字以外がある場合、そのインデックスをリストに追加
for i in new_line_list:
# 改行が最後の文字の場合はスキップ
if len(text) <= i+1:
continue
if not text[i+1].isupper():
replace_index.append(i)
# 改行後に大文字以外がある場合、改行をスペースに置き換える
new_text = ""
st = 0
for i in replace_index:
new_text += text[st:i] + " "
st = i+1
new_text += text[st:]
2-3. DeepLで英文を和文に翻訳
DeepL APIを使うにはDeepL APIへの登録が必要です.
登録後は,クレジットカード情報を入力することで,認証キーを発行できます.この後に使うので発行できたらコピーしておいてください.
DeepL APIをPythonで使うための公式のクライアントライブラリがあります.これをpipでインストールします.
pip install --upgrade deepl
このライブラリを使えば翻訳自体はとても簡単にできます.
auth_keyには先ほど発行した認証キーを設定してください.
DeepL APIとdeeplライブラリに関しては以下のサイトを参考にしました.
python で deepL API を使ってみる
import deepl
auth_key = "発行した認証キー"
# 英語から日本語に翻訳
source_lang = "EN"
target_lang = "JA"
# 翻訳
translator = deepl.Translator(auth_key)
result = translator.translate_text(new_text, source_lang=source_lang, target_lang=target_lang)
2-4. 和文をクリップボードにコピー
2-1で使用したpyperclipのcopyメソッドを使うだけです.
# 翻訳結果をクリップボードにコピー
pyperclip.copy(result.text)
3. まとめ
- 今回やったこと
- pyperclipでクリップボード周りのいろいろ
- DeepL APIで自動翻訳
今回実装したコードを以下に載せておきます.
また,自身のGitHubでも公開しています.
import pyperclip
import deepl
import settings
import re
auth_key = settings.AUTH_KEY
source_lang = "EN"
target_lang = "JA"
while True:
try:
# コピーされた英文のテキスト
text = pyperclip.waitForNewPaste(300)
# 改行のインデックスを取得
new_line_list = [i.start() for i in re.finditer("\n", text)]
# 改行後に大文字以外があるかどうか
replace_index = []
# 改行後に大文字以外がある場合、そのインデックスをリストに追加
for i in new_line_list:
# 改行が最後の文字の場合はスキップ
if len(text) <= i+1:
continue
if not text[i+1].isupper():
replace_index.append(i)
# 改行後に大文字以外がある場合、改行をスペースに置き換える
new_text = ""
st = 0
for i in replace_index:
new_text += text[st:i] + " "
st = i+1
new_text += text[st:]
# 翻訳
translator = deepl.Translator(auth_key)
result = translator.translate_text(new_text, source_lang=source_lang, target_lang=target_lang)
# 翻訳結果をクリップボードにコピー
pyperclip.copy(result.text)
except pyperclip.PyperclipException:
print("5分間入力がないため終了します")
break
except KeyboardInterrupt:
print("終了します")
break
4. 終わりに
翻訳が結構ストレスだったので,適当に作ってみたら簡単&便利すぎて感動しました.
ライブラリを作ってくれている先人に感謝!
参考文献
Python, pyperclipでクリップボードを操作(コピー、ペースト、監視)
python で deepL API を使ってみる
DeepL APIをPythonで使うための公式のクライアントライブラリ