PDF文書の翻訳ツールを作る3 (DeepL翻訳サイトにテキストデータを投げる)
筆者地方ではスギ花粉はピークを過ぎたそうです。
んが、筆者はスギは軽くってヒノキの方がつらいのです。。
そう。本当の戦いはこれから始まるのです。
こんちくわ 壁|ω・)ノ
さて、前回の記事の続きです。
今回はいよいよ翻訳する文字列をDeepLサイトに投げる処理について紹介します。
でわいきます ̄▽ ̄)ノ
Contents
前回の記事では・・・
クリップボードから文字情報を引っ張り出しすFuncrionプロシージャについて書きました。コーディングのポイントは以下の通り。
- クリップボードからのデータの出し入れにはMSfromsライブラリの DataObjectクラスのメンバーである
GetFromClipboardメソッドと GetText メソッドを利用
する - その下準備として、
Microsoft Forms 2.0 Object Library を有効に
するための参照設定を行う - クリップボードの中身を空にするのに
Application.CutCopyMode=False
が使える - クリップボードの中身が空かどうかの判定は
Application.ClipboardFormats(1) の値を参照
する
これで、Functionプロシージャ ClipBordContents()作ったのでした。
クリップボードから取得した文字列をDeepLサイトに投げる
いきなりですが、出来上がったコードです
Private Sub DeepL翻訳() 'ClipBordContents関数で取り出したクリップボードの中身targetTextに格納する Dim targetText As String: targetText = ClipBordContents() Dim URL As String: URL = "https://www.deepl.com/ja/translator" Dim objIE As SHDocVw.InternetExplorer: Set objIE = New SHDocVw.InternetExplorer objIE.Visible = True Call objIE.navigate(URL) Do While objIE.Busy = True Or objIE.readyState <> 4 DoEvents Loop 'Deeplサイトへの 'クラス名は"lmt__textarea" または "lmt__textarea lmt__source_textarea" でもおk Dim objInpTxt As MSHTML.HTMLHeaderElement Set objInpTxt = objIE.document.getElementsByClassName("lmt__textarea lmt__source_textarea lmt__textarea_base_style")(0) objInpTxt.Value = targetText SendKeys "{ENTER}" End Sub
短いコードですがそれぞれの内容について紹介しますね
IEを起動してサイトにアクセスする
VBAを使ったスクレイピングについてはいろんなところで紹介されていますのであまり詳しくは書きませんが、記事で足りない情報はGoogle先生にお伺いするとよいと思います。
まず最初に、VBAを使ったインターネットエクスプローラー(IE)の操作には、Microsoft Internet Controls(SHDocVw.DLL)ライブラリの InternetExplorerクラスメンバー
を使います。また、後述するHTMLに対する操作ではMicrosoft HTML Object Library(MSHTML.DLL)ライブラリ
を利用しますので、参照設定する下準備をしておきます。
コーディングは InternetExplorerクラスメンバーを憑依させたオブジェクト(インスタンス) objIE を生成 (New) した後に objIE.xxxx と記述してメンバーを呼び出しながら進めていきます(インスタンスの名前はなんでもおk)。
コード的には、以下の2つの構成がほぼお約束的な書き方になっています。
' InternetExplorerクラスから、インスタンスobjIEを生成(New) ' .Visibleメソッドで IEウィンドウを表示する Dim objIE As SHDocVw.InternetExplorer: Set objIE = New SHDocVw.InternetExplorer objIE.Visible = True
2.目的のサイトにアクセスして、読み込み待ちをする
' .Navigateメソッド(引数URL:アクセスしたいサイトのURL)、目的のサイトにアクセスする ' .Busyまたは .ReadyStateプロパティで読み込み完了したか否かを判定して、読み込み未完の場合はOSに処理を渡す Call objIE.navigate(URL) Do While objIE.Busy = True Or objIE.readyState <> 4 'objIE.readyState < READYSTATE_COMPLETEでもおk DoEvents Loop
.Busyは 文字通りIEが忙しい状態かどうか。
.Readystate はサイトの読み込み状態を示します(Readystateプロパティの戻り値については以下の通り)
列挙体記述 | 定数 | 説明 |
---|---|---|
READYSTATE_UNINITIALIZED | 0 | 未完了状態 |
READYSTATE_LOADING | 1 | IEオブジェクトのロード中 |
READYSTATE_LOADED | 2 | IEオブジェクトのロード完了。ただし、操作不可能 |
READYSTATE_INTERACTIVE | 3 | IEオブジェクトの操作可能状態 |
READYSTATE_COMPLETE | 4 | IEオブジェクトの全データ読み込み完了 |
DoEventsについては以下のサイトが参考になります
DeepLの翻訳ウィンドウにテキストを入れる
今回のコードのメインエベント的な部分ではあるのですが、実わ理解不十分なところもあって、手探りでこうしたらなんかうまくいった的な感じなコードの紹介になってしまいます。
すまそん。。。
で、クリップボードから取り出した文字列情報はすでに変数に代入済み。ぢゃぁ、それをDeepLサイトの所定の位置に投入するためには、HTMLで記述されているDeepLサイトのどの要素をどういじればいいのか?と、いうのがHTML知識がほぼゼロな筆者には大問題なわけです。
でもEdgeの機能いじくり倒すことで、大体コレ的なものをつかむことができました。
恥ずかしげもなく大公開すると、
手順1.Edgeの開発者ツールを起動します
手順2.開発者ツールをポチすると、なんかコードが右にずらーっと出現します。
思わず気が遠くなりそうになりますが、意識をつないでその上にあるマウスポインタの絵をクリック
します
すると、該当するコード部分がハイライトされます。
この状況でもまだまだ気持ちを保つのにエネルギーが必要な状況ではありますが、落ち着いて示された先を見ると、
<textarea class="lmt__textarea lmt__source_textarea lmt__textarea_base_style" ...... lang></text area>
というHTML特有の機能単位を示す記述のパターン(<xxx>...</xxx>)が目に入って、この辺のclassをいじくればいいのかもしれない・・・ と、希望の糸が見えてきます。
と、いうわけでそんな根拠のない見通しとGoogle先生のご助言を基に試行錯誤して作成したのが以下のコードになります。
Dim objInpTxt As MSHTML.HTMLHeaderElement 'クラス名は"lmt__textarea" または "lmt__textarea lmt__source_textarea" でもおk Set objInpTxt = objIE.document.getElementsByClassName("lmt__textarea lmt__source_textarea lmt__textarea_base_style")(0) objInpTxt.Value = targetText 'targetText:翻訳したいテキストを格納
” lmt_textarea lmt_source_textarea lmt__textarea_base_style” クラスで指定されるオブジェクトをgetElementsByClassName メソッドで特定
して、そこに翻訳したい文字列を代入するような記述になりました。
実行すると、DeepL画面の目的の場所に翻訳したい文字列が入ったので、これでヨシ!!
"(0)" がオブジェクトの要素ゼロ番を意味するのか、配列のインデックス番号なのか結局わからなかったけろヨシ!
識者の方のご意見お待ちしております<(_ _)>
Enterする
DeepLサイトは、翻訳したい文章をウィンドウにコピペすると自動で翻訳を開始します。つまり "翻訳ボタンがない" のですね。
試行錯誤しつつもめでたく所定の枠に目的の文書を導入することに成功した訳ですが、そのままだと何時までたっても翻訳が始まらず、ぽっつーんな感じになります。でも、追加で "Enter" すれば翻訳が始まるため、
SendKeys "{ENTER}"
ハイ。Enterキーをコード的に押すヤツですね。
これを最後に差し込むことで、ちゃんと翻訳を始めように仕向けることができました。
本当は自動翻訳開始のコマンドを探したかったのですが、ビジュアル頼みの解読では手がかりすらつかむことができず-ω-)
まとめ
今回の記事ではクリップボードから取得した文字列情報を DeepLサイトの所定の位置に挿入して翻訳を開始させるコードを紹介しました。いくつかの参照設定とそのメンバーを使う
ことで、IEを起動 → サイトを開いて → 好きな操作をする というこがVBAでちゃんとできることを自分なりに確認することができました。
一方でDeepLサイト操作など、頼みのGoogle先生がほとんどご存じないとなると一気に苦戦するわけでして、、当たり前ではありますがHTMLについてのある程度の知識は必要ですね。
今回は#ノンプロ研 御大 タカーシさんの隣it
のシリーズ記事をあれこれ参照しながら試行錯誤させていただきました。
時間はかかりましたが何とかなるものですね。
さて今回の記事で、英文PDFの文章をコピーしてそれをそのままDeepLサイトに自動で放り込んで翻訳してもらう本体コードはできました。
次回以降の記事ではもう一歩踏み込んで、DeepL翻訳を利用する上で気が付いた課題とそれに合わせたコードの追加や、使いやすさを追求した工夫について紹介したいと思います。
でわまた~  ̄▽ ̄)ノシ