粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

Pythonで文章整形(改行除去)DeepL翻訳の流れを自動化させてみる

会社のプロキシを通すと諸々のサービス繋げなくて困るねという話です。

概要

  • PythonをつかってShaperの機能を代替
  • DeepLに翻訳を投げて結果を取得する機能も追加
  • プロキシなどの成約で特定のサイトにアクセスできなくてもきちんと翻訳できる!

DeepLはまだスクレイピング行為を明確に禁止していない用に見えますが,あんまり望んでいないとは思います。有料API売ってるくらいなので。

DeepL翻訳を使った高速英文読解

Google翻訳やみらい翻訳と並びDeepLは精度も良く使い勝手も結構良い翻訳サービスです。

ただ,PDFから変換する際には変にはいる改行などを除去する一連の作業が必要になります。

koovet.com

この際のShaperというサイトにアクセスできなかったためPythonスクリプトを書いたのが始まりです。

なお,DeepLもGoogle翻訳も便利なChrome拡張機能があるので自宅用にはあまり必要ないプログラムな気がします。

1. TKinterを用いたGUI文章整形

整形手法は

  • ボックスの中のテキストをCopy
  • 改行と改行前のハイフンを削除して変わりにSpaceを代入

とします。クリップボードツールとしてpyperclipのインストールが必要です。

import tkinter as tk
import pyperclip
import re

# 行末のハイフンと改行を削除
def shaping(txt):
    lines = re.split("\n\r",txt)
    output = ""
    for line in lines:
        if line:
            if line[-1] == "-":
                output += line[:-1] + " "
            else:
                output += line + " "
    return output

root = tk.Tk()
# 入力を取得
def retrieve_input():
    inputValue=textBox.get("1.0","end-1c")
    shaped = shaping(inputValue)
    # copy to clip board
    pyperclip.copy(shaped)
    print("Copied ",len(shaped),"charactors!")


# delete box
def deletebox():
    textBox.delete(1.0, tk.END)

# Create GUI
textBox=tk.Text(root, height=40, width=40)
textBox.pack()
buttonCopy=tk.Button(root, height=1, width=10, text="Copy", 
                    command=lambda: retrieve_input())
buttonClear=tk.Button(root, height=1, width=10, text="Clear", 
                    command=lambda: deletebox())

#command=lambda: retrieve_input() >>> just means do this when i press the button
buttonCopy.pack()
buttonClear.pack()

tk.mainloop()

Copyボタンを押すことで整形された文章がクリップボードに残るのでそのままDeepLのサイトにペーストします。 ボタン横に並べろとかいろいろありますが,とりあえずMinimal Effortで作成しました。

2. Seleniumを用いた翻訳取得

残りの部分は下記の手順で出来ました。

必要なのは

  • Seleniumのインストール
  • Chromedriverのインストール

です。

qiita.com

ただ,煩雑な割には得るものは少なかった印象です。

具体的な動作としてはコードを走らせるとChromeが立ち上がって,そこでの操作をPython経由で送受信しているのであまり工程省略できている感じはしません。

f:id:ossyaritoori:20200910235529p:plain
後ろで結局Chromeが立ち上がっちゃうのであんまり自動化している感じはしない。

まとめ

拡張機能使えないってなんやねん

依存パッケージインストール

pipを許容するなら以下のように簡単です。

pip install pyperclip selenium chromedriver-binary
  • chromedriver binary install

非常にだるいですがChromeDriverはChromeのバージョンに合わせなくてはいけません。

qiita.com

pip install chromedriver-binary==85.0.4183.87.0

コード

  • これは正直あんまりエレガントではないです。
import tkinter as tk
import pyperclip
import re
from selenium import webdriver
import time
import chromedriver_binary

# Scraping part
load_url = "https://www.deepl.com/ja/translator"
driver = webdriver.Chrome()  #  driver = webdriver.Chrome("c:/work/chromedriver.exe")
driver.get(load_url)


# send translation request
def translate(txt):
    input_selector = "#dl_translator > div.lmt__sides_container > div.lmt__side_container.lmt__side_container--source > div.lmt__textarea_container > div > textarea"
    driver.find_element_by_css_selector(input_selector).send_keys(txt)
    while 1:
        Output_selector = "#dl_translator > div.lmt__sides_container > div.lmt__side_container.lmt__side_container--target > div.lmt__textarea_container > div.lmt__translations_as_text > p > button.lmt__translations_as_text__text_btn"
        Outputtext = driver.find_element_by_css_selector(Output_selector).get_attribute("textContent")
        if Outputtext != "" :
            break
        time.sleep(1)
    print(Outputtext)
    pyperclip.copy(Outputtext)


# 行末のハイフンと改行を削除
def shaping(txt):
    lines = re.split("\n\r",txt)
    output = ""
    for line in lines:
        if line:
            if line[-1] == "-":
                output += line[:-1] + " "
            else:
                output += line + " "
    return output

root = tk.Tk()
# 入力を取得
def retrieve_input():
    inputValue=textBox.get("1.0","end-1c")
    shaped = shaping(inputValue)
    # copy to clip board
    pyperclip.copy(shaped)
    print("Copied ",len(shaped),"charactors!")

def copyandtranslate():
    retrieve_input()
    translate(pyperclip.paste())

# delete box
def deletebox():
    textBox.delete(1.0, tk.END)

# Create GUI
textBox=tk.Text(root, height=40, width=40)
textBox.pack()
buttonCopy=tk.Button(root, height=1, width=10, text="Translate", 
                    command=lambda: copyandtranslate())
buttonClear=tk.Button(root, height=1, width=10, text="Clear", 
                    command=lambda: deletebox())

#command=lambda: retrieve_input() >>> just means do this when i press the button
buttonCopy.pack()
buttonClear.pack()

tk.mainloop()

Bug Fix

TODO

  • Chromedriverがプロキシで入らなそうな雰囲気があるので対策を考える
  • ウィンドゥがバックグラウンドで開かないようにしたい
  • 見た目の洗練(優先度低)