こんにちは、blueです。
英語の文書を読むとき、
- 毎回翻訳サイトを使う必要があり大変
- 全文翻訳だと有料だし、原文を見直す際手間だ
ということはないでしょうか?
しかし、スクレイピングの知識を使えば翻訳サイトをその都度使う必要なく、日英併記された文書を作成、読むことができるようになります。
この記事では
- SeleniumBasicで日英併記されたWord文書を作成する為の具体的なコード
について紹介していますので、ぜひ読んでみてください。
ちなみに他サイトの引用ですがスクレイピングに関しては使用方法によっては違法となるケースも存在します。
スクレイピングは違法?3つの法律問題と対応策を弁護士が5分で解説
IT弁護士に聞く「企業としてのスクレイピングは違法なのか?」
使用に関しては自己判断でお願いします。
VBAを使ったものではありませんが、Seleniumを勉強する為の基本的な書籍です。ブラウザやキー操作の基本的なコマンドは共通していますのでコードを書く際の参考になります。
VBAの書籍の中でSeleniumBasicを取り上げている数少ない書籍です。ページ数としては20ページほどですがとてもわかりやすく書かれています。またVBA全般を網羅した内容が書かれており、長く使用することができます。
全コード
今回のコードは以下になります。長いですが後で詳しく説明していますので安心してください。
なおこのコードを扱う際には「ツール」-「参照設定」で「Selenium Type Library」と「Microsoft Word XX.X Object Library」にチェックを入れるようにしてください。
Sub WordTranlsation()
Dim FileName As String
Dim wb As Workbook
Dim Driver As New Selenium.WebDriver
Const Url As String = "https://www.deepl.com/ja/translator"
'Wordファイルを選択する
FileName = Application.GetOpenFilename(FileFilter:="Wordファイル,*.doc*")
If FileName = "False" Then
Exit Sub
End If
'Wordファイルを開く
Dim wd As Word.Application
Dim doc As Document
Set wd = New Word.Application
wd.Visible = True
Set doc = wd.Documents.Open(FileName, False, True)
'Seleniumを立ち上げる
Driver.Start "Chrome"
'翻訳サイトを立ち上げる
Driver.Get Url
'原文の言語を選択する
Driver.FindElementByCss("#panelTranslateText > div.lmt__sides_container > section.lmt__side_container.lmt__side_container--source > div.lmt__language_container > div > button").Click
Driver.Wait 3000
Driver.FindElementByCss("#panelTranslateText > div.lmt__sides_container > section.lmt__side_container.lmt__side_container--source > div.lmt__language_select__menu.lmt__language_select__menu_source.lmt__language_select__menu_three_columns.lmt__language_select--open.focus-visible-inside-container.lmt__language_select--open_2 > div.lmt__language_wrapper > div:nth-child(3) > button:nth-child(5)").Click
Dim par As Paragraph
Dim SourceSentense As String '原文
Dim TranslatedSentense As String '翻訳文
'各段落を取得し、翻訳する
For Each par In doc.Paragraphs
SourceSentense = par.Range.Text
If SourceSentense <> Chr(13) Then '改段落のみは処理しない
'原文に文字列を入力
Driver.FindElementByCss("#dl_translator > div.lmt__text > div.lmt__sides_container > section.lmt__side_container.lmt__side_container--source > div.lmt__textarea_container > div.lmt__inner_textarea_container > textarea").Clear
Driver.FindElementByCss("#dl_translator > div.lmt__text > div.lmt__sides_container > section.lmt__side_container.lmt__side_container--source > div.lmt__textarea_container > div.lmt__inner_textarea_container > textarea").SendKeys SourceSentense
Driver.Wait 5000
'訳文の文字列を取得
TranslatedSentense = Driver.FindElementByCss("#target-dummydiv").Attribute("textContent")
TranslatedSentense = Replace(TranslatedSentense, vbCrLf, "") 'Deeplの場合翻訳文にvbCrLfが含まれている為削除
'段落の末尾に翻訳文を追加する
doc.Range(0, par.Range.End - 1).InsertAfter (vbVerticalTab & TranslatedSentense)
End If
Next
Application.DisplayAlerts = False
doc.SaveAs2 doc.Path & "\(JP-EN)" & Dir(FileName)
Application.DisplayAlerts = True
End Sub
最終的なイメージは以下になります(BeforeとAfter 赤枠が翻訳文)
次から各コードについて説明します
コードの構成
今回のコードの構成は以下になります。
- Wordの文書を開く
- DeepLサイトを開く
- DeepLで翻訳できる環境を作る
- 文書から各段落を取得する
- 原文を入力する
- 翻訳文を取得する
- Wordに出力する
- Wordを保存する
それぞれについて説明します。
Wordの文書を開く
FileName = Application.GetOpenFilename(FileFilter:="Wordファイル,*.doc*")
If FileName = "False" Then
Exit Sub
End If
'Wordファイルを開く
Dim wd As Word.Application
Dim doc As Document
Set wd = New Word.Application
wd.Visible = True
Set doc = wd.Documents.Open(FileName, False, True)
ApplicationのGetOpenFilenameメソッドでWordファイルを選択します。
キャンセルを押した場合は”False”が返るのでその場合は処理を終了するようにしています。
その後Microsoft Wordを開き、対象のファイルを開くようにしています。
DeepLサイトを開く
'Seleniumを立ち上げる
Driver.Start "Chrome"
'翻訳サイトを立ち上げる
Driver.Get Url
StartメソッドでSelenium WebDriverを立ち上げます。その後GetメソッドでURLのサイトを開きます。
StartメソッドとGetメソッドについての詳しい記事はこちら
DeepLで翻訳できる環境を作る
'原文の言語を選択する
Driver.FindElementByCss("#panelTranslateText > div.lmt__sides_container > section.lmt__side_container.lmt__side_container--source > div.lmt__language_container > div > button").Click
Driver.Wait 3000
Driver.FindElementByCss("#panelTranslateText > div.lmt__sides_container > section.lmt__side_container.lmt__side_container--source > div.lmt__language_select__menu.lmt__language_select__menu_source.lmt__language_select__menu_three_columns.lmt__language_select--open.focus-visible-inside-container.lmt__language_select--open_2 > div.lmt__language_wrapper > div:nth-child(3) > button:nth-child(5)").Click
FindElementByCssメソッドで対象の要素を取得し、Clickメソッドでボタンを押しています。
具体的には以下2つのボタンを押しています。
その1
その2
ちなみにその1を押してからその2が表示されるのには時間がかかるため、Waitメソッドで3秒待っています。
文書から各段落を取得する
Dim par As Paragraph
Dim SourceSentense As String '原文
Dim TranslatedSentense As String '翻訳文
'各段落を取得し、翻訳する
For Each par In doc.Paragraphs
SourceSentense = par.Range.Text
~~~
Next
Wordの全段落についてはParagraphsプロパティで取得することができます。
取得したParagraphsオブジェクトはコレクションの為、For Each~Nextで各段落のオブジェクトを取得することができます。
それぞれの段落のテキストはRangeオブジェクトのTextプロパティで取得することができます。
Word VBAに関しては以下の書籍を見ればマスターできます。
原文を入力する
'原文に文字列を入力
Driver.FindElementByCss("#dl_translator > div.lmt__text > div.lmt__sides_container > section.lmt__side_container.lmt__side_container--source > div.lmt__textarea_container > div.lmt__inner_textarea_container > textarea").Clear
Driver.FindElementByCss("#dl_translator > div.lmt__text > div.lmt__sides_container > section.lmt__side_container.lmt__side_container--source > div.lmt__textarea_container > div.lmt__inner_textarea_container > textarea").SendKeys SourceSentense
Driver.Wait 5000
FindElementByCssメソッドで翻訳するテキストの入力場所の要素を取得しています。
具体的には以下になります。
なお繰り返し処理になる為、Clearメソッドで前回の文字を消去したのちに、SendKeyメソッドでテキストを入力しています。
SendKeyメソッドについての詳しい記事はこちら
その後翻訳文の取得になるのですが、文章が長いと翻訳に処理がかかる為、Waitメソッドで5秒待つようにしています。
翻訳文を取得する
'訳文の文字列を取得
TranslatedSentense = Driver.FindElementBCss("#target-dummydiv").Attribute("textContent")
TranslatedSentense = Replace(TranslatedSentense, vbCrLf, "") 'Deeplの場合翻訳文にvbCrLfが含まれている為削除
翻訳文については少し注意が必要です。
翻訳自体はJavaScriptを使って行われる為、翻訳文はHTMLではなく、JavaScriptの方に表示されます。
デベロッパーツールのJavaScriptの見方についてはこちら
今回の翻訳文に関しては以下のようにプロパティのtextContentに表示されています。
そこでAttributeメソッドの引数を“textContent”として翻訳文書を取得しています。
Attributeメソッドについての記事はこちら
なお、DeepLで取得した文にはvbCrLf(改段落)が含まれる為、Replace関数で削除しています。
Wordに出力する
'段落の末尾に翻訳文を追加する
doc.Range(0, par.Range.End - 1).InsertAfter (vbVerticalTab & TranslatedSentense)
End If
Next
ここでは取得した段落の一番最後に改行+翻訳文を入れるようにしています。
Wordを保存する
Application.DisplayAlerts = False
doc.SaveAs2 doc.Path & "\(JP-EN)" & Dir(FileName)
Application.DisplayAlerts = True
最後にファイル名に(JP-EN)をつけて保存しています。
今回のまとめ
今回はSelenium-VBAを使ったWord内の文章の翻訳について説明しました。
このコードを使えば、Word文書を日英併記にすることが可能です。
ただこのサイトは処理にJavaScriptを使っており、安定的にデータをとるのに時間がかかるのが難点です。
以下の記事では「Web APIを使ったDeepLでの文章の翻訳」についても解説しているので、こちらの記事も併せて読んでみてください。
Seleniumを勉強するには書籍を使うのもおすすめです。以下の書籍はSeleniumを勉強する際の基本的なものになるのでこちらも是非ご検討ください。
VBAを使ったものではありませんが、Seleniumを勉強する為の基本的な書籍です。ブラウザやキー操作の基本的なコマンドは共通していますのでコードを書く際の参考になります。
VBAの書籍の中でSeleniumBasicを取り上げている数少ない書籍です。ページ数としては20ページほどですがとてもわかりやすく書かれています。またVBA全般を網羅した内容が書かれており、長く使用することができます。
SeleniumBasicでのWebスクレイピングに関する記事はこちらをどうぞ
Web-APIを用いたデータ取得に関する記事はこちらをどうぞ
【VBA】Web APIを使ってデータを取得する(OpenWeatherMap)1
【VBA】Web APIを使って時間別天気予報を取得する(気象庁API)
【VBA】Web APIを使ってLINE通知を行う(LINE Notify)1
【API-VBA】Web APIを使って翻訳をする(DeepL API)
コメント