sawaki のすべての投稿

sawaki について

技術士(化学部門、総合技術監理部門) 沢木技術士事務所 代表

Excel VBAでSeleniumBasicを使用してChromeを操作し、J-PlatPatから公報をダウンロードする方法

ここまで、Excel VBAを使ってインターネットエクスプローラ(IE)を制御することで、J-PlatPatから特許公報テキストをダウンロードすることができるようになった。ところが、どうやらマイクロソフトは IE を見限ったようで、今後は徐々にサポート対象外となるような話が出ている。VBAでインターネットにアクセスし、ウェブページを操作したり、データをダウンロードしようとしたら、現時点ではIEを使うのが手っ取り早い方法ということになるが、今後はそれがどうなるのか、今の時点では特にアナウンスはされていないようだ。

また、IE だと、Espacenet にアクセスしても一部の公報で表示がうまく行われないという現象も見られるようなので、何とかしたいと考えていたところでもあり、この際、IE以外のブラウザを操作して、インターネットからデータをダウンロードする方法として、SeleniumBasic を使用した Google Chrome の操作にチャレンジしてみた。

ここでは、IEを操作するマクロと比較しやすいように、ここまで説明してきた J-PlatPat からテキスト公報をダウンロードする操作と全く同じ動作をするマクロを、SeleniumBasic を使用して行うことにした。IEを操作するマクロの詳細については、「Excel VBAを使用してJ-PlatPatから公報テキストをダウンロードする方法」の(1)(2)(3)(4)(5)を参照いただきたい。

1.準備

Excel VBAでSeleniumBasicを使用してGoogle Chromeを操作するためには、SeleniumBasicのインストール、Chromeドライバーのインストール、Excel VBAへの参照設定といった事前作業が必要となる。これらの作業については、いくつかのサイトで丁寧に説明がなされているので、これらを参照願いたい(例えば、以下のサイト)。

 ・VBAのスクレイピングを簡単楽にしてくれるSelenium
 ・非エンジニアにこそ伝えたいSeleniumBasic
 ・Seleniumを使ってVBAからchromeブラウザ操作(VBA編)

2.J-PlatPatのトップページを開く

最初に、Chromeを立ち上げ、J-PlatPatのトップページを開く。既にChromeが立ち上がっている場合には、それとは別の新たなウィンドウで立ち上がる。なお、SeleniumBasicが立ち上げた新たなChromeのウィンドウの左上には「Chromeは 自動テスト ソフトウェアによって制御されています。」という表示が出る。

Dim Driver As New Selenium.WebDriver
Dim url As String

url = “https://www.j-platpat.inpit.go.jp/”

Driver.Start “chrome”
Driver.Get url

Do While InStr(Driver.PageSource, “>検索<“) = 0
      DoEvents
      Application.Wait [Now()] + 100 / 86400000
Loop

所定のURLのサイトを開くところまでは特に問題はない。SeleniumBasicの場合、ブラウザがビジーの間は処理が戻ってこないようなので、IE制御の場合にはお約束のように多用した objIE.readystate と objIE.Busy をチェックする Do While ループは必要ない。それでも、表示が完了したかどうかのチェックは必要なので、ここではHTML中に”>検索<“が含まれていることが確認できるまで待機している。なお、IE制御のときの objIE.document.body.innerHTML に該当するのが、SeleniumBasic では Driver.PageSource である。

3.公報番号を入力し、検索ボタンをクリックし、検索結果一覧の表示完了を確認する

Dim patnum As String
Dim i As Integer
patnum = “特開2018-010101”

Driver.FindElementById(“s01_srchCondtn_txtSimpleSearch”).Clear
Driver.FindElementById(“s01_srchCondtn_txtSimpleSearch”).SendKeys patnum
Driver.FindElementByName(“s01_srchBtn_btnSearch”).Click

i = 1
Do While InStr(Driver.PageSource, “特願”) = 0 And i < 300
      DoEvents
      i = i + 1
      Application.Wait [Now()] + 100 / 86400000
Loop

前半部分では、テキストボックス”s01_srchCondtn_txtSimpleSearch”に公報番号を入力し、検索ボタン”s01_srchBtn_btnSearch”をクリックしている。IE制御の際には、何やらややこしい操作が必要だったのだが、SeleniumBasicでは教科書通りに SendKeys でテキストを送信し、ボタンをクリックすることで問題なく検索される。ただし、テキストボックス内に既にテキストが入っている場合には、それに追加されてしまうので、事前にクリアしてからテキストを送信するようにしている。

後半部分では、検索結果一覧表が表示されたことを確認するため、”特願”という語句が検出されるか、または繰り返し回数が300回となるまで、ループさせている。

4.検索結果一覧にて公報のリンクをクリックし、文献表示画面を取り込む

Dim wEle As WebElement
Dim flag As Integer

flag = 0
i = 1
Do While flag = 0 AND i < 300
      For Each wEle In Driver.FindElementsByTag(“a”)
            If InStr(wEle.Text, patnum) > 0 Then
                  wEle.Click
                  flag = 1
                  Exit For
            End If
      Next
      Application.Wait [Now()] + 100 / 86400000
      i = i + 1
Loop

Set wEle = Nothing

ここでは、Driverの中に含まれるすべてのAタグの中から、所望の公報番号をテキストとして持っているAタグを見つけ、これをクリックする。この部分では使っている関数名が微妙に異なっているが、IE制御のときとほとんど変わりがない。クリック操作により、特許・実用新案文献表示画面が別ウィンドウで表示される。

このままでは、オブジェクト変数Driverには、まだ最初のウィンドウが入ったままであり、新たに開いたウィンドウの操作ができないので、切り換える。IE操作の際には、ここで立ち上がっている全てのウィンドウの中から所望のウィンドウを探し出し、そのウィンドウをオブジェクト変数に取り込む必要があったが、SeleniumBasicでは、次の1行で済む。

Driver.SwitchToNextWindow

これで新たに開いたウィンドウが、変数Driver に取り込まれるのだが、この後このウィンドウを閉じて、元のウィンドウを操作したりする際に、今どのウィンドウを操作しているのかわかりにくいので、次のように明示的にウィンドウを取り込む方法の方が良いかもしれない。

Dim targetTitle As String

targetTitle = “特許・実用新案文献表示|J-PlatPat [JPP]”
Driver.SwitchToWindowByTitle (targetTitle)

5.「要約」、「請求の範囲」、「詳細な説明」を開く

i = 1
Do While InStr(Driver.PageSource, “図面”) = 0 And i < 300
      DoEvents
      i = i + 1
      Application.Wait [Now()] + 100 / 86400000
Loop

For Each wEle In Driver.FindElementsByTag(“a”)
      If InStr(wEle.Text, “要約”) > 0 And InStr(wEle.Text, “開く”) > 0 Then
            wEle.Click
            i = 1
            Do While InStr(wEle.Text, “開く”) > 0 And i < 300
                  DoEvents
                  Application.Wait [Now()] + 100 / 86400000
                  i = i + 1
            Loop
            Exit For
      End If
Next

Set wEle = Nothing

最初に、文献表示画面にて、”図面” という語句が表示されたのが確認されるまで、待機し、その後、折り畳まれていた 「要約」 のリンクをクリックして内容を表示させている。要約の内容が表示されると、「要約」のリンクの右側の「開く +」が「閉じる -」に変わるので、「開く」が消えたことが確認されるまで待機している。

2021/02/03 ここの部分、J-PlatPat側の仕様変更に伴い、修正。
 文献表示画面にて、最初から「要約」が開いた状態で表示されるように変更になったので、「要約」のリンクを見つけ、その横に「開く +」の表示がある場合には「要約」のリンクをクリックするが、「開く +」の表示がない(既に開いている)場合には、その操作をスキップするように変更した。

その後、「請求の範囲」と「詳細な説明」に対しても、「要約」に対して行ったのと同様の処理を行う。これによって、必要な情報が全て表示された状態となっているはずである。

6.固定URLを表示させ、表示内容をダウンロード

For Each wEle In Driver.FindElementsByTag(“a”)
      If InStr(wEle.Text, “URL”) > 0 Then
            wEle.Click
            Exit For
      End If
Next

Set wEle = Nothing

Dim Fname As String
Fname = “D:\” & patnum & “.txt”

Open Fname For Output As #1
      Print #1, Driver.PageSource
Close #1

targetTitle = “簡易検索|J-PlatPat [JPP]”
Driver.Close
Driver.SwitchToWindowByTitle (targetTitle)

前半では、全てのAタグの中から、URLボタンを探し、これをクリックして固定URLを表示させている。ここまでの操作により、オブジェクト変数 Driver に必要な情報がすべて取り込まれたので、Driver.PageSource をテキストファイルに書き込んでいる。さらにこのウィンドウをクローズしたのち、SwitchToWindowByTitleで、検索結果一覧表が表示されている最初のウィンドウに操作を移す。これで、上の「4.」に戻って、次の公報のリンクをクリックして詳細画面を開くといった一連の操作を継続することが可能となる。

Excel VBAを使用してJ-PlatPatから公報テキストをダウンロードする方法(5)

9.「要約」、「請求の範囲」、「詳細な説明」を開く

ここまでの操作で、目的の公報の文献表示画面が開き、このウインドウを変数 objIE2に取り込むことができた。ここでも、次の操作に入る前に表示の完了を確認することが重要である。既にオブジェクトの読み込みまで完了しているのだから、問題なさそうなものだが、実際にここで表示完了の確認をせずに、次の操作として、「要約」のリンクを探してクリックしようとすると、「要約」のリンクが見つからないという事態が頻繁に発生する。そこで、この画面の表示が完了したことを、ここでは”図面”という語句の表示によって確認する(”図面”ではなくて、”詳細な説明”でも良いはず)。

i = 1
Do While InStr(objIE2.document.body.innerHTML, “図面”) = 0 And i < 300
      DoEvents
      i = i + 1
      Application.Wait [Now()] + 100 / 86400000
Loop

さて、この状態では、書誌だけが内容表示されており、要約、請求の範囲、詳細な説明は、閉じた状態となっていて内容は表示されていない。そのため、これらを全て開いた状態にして、内容を表示させる必要がある。(例外があって、サイズが非常に大きい公報は、書誌、要約、請求の範囲、詳細な説明が、それぞれのブロックに分割されず、1つにまとまった状態になった上で、複数のページに分割されて表示される。例えば、特開2019-010101)

そこで、下図の④、⑤および⑥のリンクをクリックすることで、それぞれ「要約」、「請求の範囲」および「詳細な説明」の内容を表示させてやる。

ここでは「要約」をクリックし、内容を表示させる処理についてコードを下に示す。

For Each objtag In objIE2.document.getElementsByTagName(“a”)
      If InStr(objtag.outerHTML, “要約”) > 0 And InStr(objtag.Text, “開く”) > 0 Then
            objtag.Click
            Do While objIE2.readyState <> 4 Or objIE2.Busy
                  DoEvents
            Loop

            i = 1
            Do While InStr(objtag.Text, “開く”) > 0 And i < 300
                  DoEvents
                  Application.Wait [Now()] + 100 / 86400000
                  i = i + 1
            Loop
            Exit For
      End If
Next

Set objtag = Nothing

最初に、このページ(objIE2)の全てのAタグの中から、outerHTMLに”要約”を含むタグを探し、これをクリックする。クリックした後、objIE2.readyState と objIE2.Busy を Do While~Loop でチェックする準備完了待ち処理を行う。内容が表示されると、「要約」のリンクの右側の表示が「開く +」から「閉じる -」に変わるので、その確認を行う。この確認を行わずに、次の処理に進むと、準備ができていないうちに次の命令が来てしまうため、その処理を実行できないことがあるようだ。ここでは、「開く」が表示されたままであれば、「開く」が表示されなくなるまで、最大30秒間待機する、という処理にしている。

2021/02/03 ここの部分、J-PlatPat側の仕様変更に伴い、修正。
 文献表示画面にて、最初から「要約」が開いた状態で表示されるように変更になったので、「要約」のリンクを見つけ、その横に「開く +」の表示がある場合には「要約」のリンクをクリックするが、「開く +」の表示がない(既に開いている)場合には、その操作をスキップするように変更した。

実際には、この場面には例外がいくつかある。特許公報や公告公報の場合には、そもそも要約が含まれていないので、”要約”リンクが表示されない。また昭和57年以前の公開公報などの古いものは、このページが開いたときに、要約、請求の範囲、詳細な説明が閉じた状態となっている点は同じなのだが、”要約”と”請求の範囲”のリンクをクリックしても、その内容が表示されることはなく、今まであったリンクそのものがそれぞれ消えてなくなってしまう一方で、”詳細な説明”をクリックすると、特許請求の範囲と詳細な説明が1つのブロックとしてまとめて表示される。(画面からは”要約”の文字やリンクが消え、objIE2.document.body.innerHTMLからも”要約”は消えてしまうが、objtag.Textの中には、”開く”がそのまま残っているので、それらを考慮して処理する必要がある)そんなわけで、ここの処理は、これら様々な例外にも対応した複雑なものにする必要があるが、ここでは省略する。

続いて、「要約」に対して行ったのと同様の処理を、「請求の範囲」と「詳細な説明」に対しても行う。これは、”要約”の部分を、それぞれ”請求の範囲”と”詳細な説明”に置き換えるだけでよい。これによって、このページには、書誌、要約、請求の範囲、詳細な説明が、それぞれ開いた状態で表示されているはずである。(公報によっては、例外もあるが。(特許公報、公告公報、古い公報など))

10.固定URLを表示

書誌、要約、請求の範囲、および詳細な説明の全てがそれぞれ開いた状態になったので、最後に、この公報の固定URLを取得する。これには、このページの右上に並んでいるいくつかのボタンのうち、「URL」ボタン(下図の⑦)をクリックする。

すると、次のように、URLが表示されたメッセージがポップアップする。 (このとき、2.事前設定、(2) IEの設定、②のスクリプトによる貼り付け処理の設定を正しく行っていないと、ここの処理がうまく動かないので、必ず事前設定を行っておくことが重要である)。

URLボタンをクリックする処理は、次の通り。

For Each objtag In objIE2.document.getElementsByTagName(“a”)
      If InStr(objtag.outerHTML, “URL”) > 0 Then
            objtag.Click
            Exit For
      End If
Next

Set objtag = Nothing

11.表示内容をダウンロード

URLはクリップボードにコピーされているはずだが、ここではわざわざクリップボードの中身を見に行ったりせず、また、この「URLコピー」というメッセージを消すこともなく、ここで表示されているウインドウ(objIE2)の中身を全部まとめてダウンロードする。

Dim Fname As String

Fname = “D:\” & patnum & “.txt”

Open Fname For Output As #1
      Print #1, objIE2.document.body.innerHTML
Close #1

objIE2.Quit
Set ObjIE2 = nothing

ここで、objIE2.document.body.innerHTML には、この公報の、書誌、要約、請求の範囲、詳細な説明、およびURLが全て含まれているので、innerHTMLをそのまま全部ファイルに書き込んでみた。後で、このファイルを読み込んで、必要な情報をそこから取り出したり、加工したりすればよい(もちろん、ファイルに書き込まず、変数に取り込んで、引き続き様々な処理を行っても良い)。

最初に検索窓に入力した複数の公報のうち、次の公報をダウンロードするためには、「7.検索結果一覧にて公報のリンクをクリック」に戻って、objIE の中から次の公報のAタグを探してクリックする操作以降を順次繰り返せばよい。

J-PlatPat側の応答速度、ネットの速度、こちらのPCの速度など、様々な要因によって、全体の処理速度は大きく影響を受けるため、早いときには1件5秒以内に操作を終えることができる一方、遅いときには1件に30秒以上かかるときもあるのだが、与えられた状況の下で、ほぼ最短時間で処理できるようになったのではないかと思われる。最初は、1つ1つの処理の前に、数秒間ずつのwaitを入れていたが、それでも応答の遅いときにはエラーが出たり、取りこぼしが出たりしていたのがウソのように、ほぼ問題なくサクサクと処理を終えることができるようになったようだ。そのポイントとなったのは、それぞれの処理の前に、都度、その準備が完了していることを何らかの方法で確認するルーチン(次の段階の表示が行われたことを確認するループや、前の段階の表示が消えたことを確認するループなど)を入れることであった。少なくともJ-PlatPatを操作する場合には、この方法は非常に有効であると言えそうだ。

一応、これで目的の処理を終えることができたようなので、今回の連載はこれで終わりにしたい。質問やコメントがあれば、遠慮なく書き込んでください。

Excel VBAを使用してJ-PlatPatから公報テキストをダウンロードする方法(4)

6.検索結果一覧の表示完了を確認

ここまでの操作で、J-PlatPatのトップページのテキストボックス(検索窓)に公報番号を入力し、検索ボタンをクリックすることができた。これにより、下図のような検索結果一覧表が表示される。これは別のURLを持つ新たなページに遷移したわけでもないし、新たなウインドウやタブが開いたわけでもなく、今まで表示されていたJ-PlatPatトップページの中央部の検索窓と検索ボタンだけを残し、上部と下部が消去され、検索ボタンの下側に、新たに検索結果一覧表が表示されたものである。このような動的な表示の変化はJavaScriptで行われている。

次に、上図の検索結果一覧表にて、赤丸で囲んだ③のリンクをクリックしたいのだが、その前に、この動的な表示の書き換えが完了したことを確認する必要がある。実際、検索ボタンをクリックした後、objIE.readyState と objIE.Busy を Do While~Loop でチェックするお約束の表示完了待ち処理を行った後に、次の操作(所望の公報のリンクを探して、これをクリック)を行おうとすると、このリンクが見つからない、という不具合がしばしば起こる。やはり、JavaScriptによる動的な表示が完了したことを確認してから次の操作に進む必要があるようだ。

この場面では、一覧表の中の “特願” という語句に着目した。今回は特許だけを対象にしているので、必ず所望の公報の出願番号が “特願**” と表示されるはずである(該当する公報が見つからない、等のエラーが起こる場合を除く)。しかもこれは、検索結果一覧表の中に表示されるので、”特願” という語句が検出できるということは、検索結果一覧表の表示が完了したことを意味していると考えてもよさそうだ。

Dim i As Integer

i = 1
Do While InStr(objIE.document.body.innerHTML, “特願”) = 0 And i < 300
      DoEvents
      i = i + 1
      Application.Wait [Now()] + 100 / 86400000
Loop

この Do While~Loopは、このページに”特願”という語句が検出されるか、またはこのループの繰り返し回数が300回になるまで、繰り返される。ループ1回について100ミリ秒の休止を入れているので、300回で約30秒間となる(もっと長時間待ちたいときには、ここの回数を増やせばよい、30秒間はあくまでも一例)。つまり、”特願”が表示されるまで最大30秒間待機することになる。実際のプログラムでは、ここで表示される可能性のあるエラーメッセージが何種類かあるので、それぞれに対応した処理を行う必要があるし、ここで繰り返し回数が300回となった場合の処理も別途必要となるであろう(繰り返し回数が300回になったということは、公報が1つも見つからなかった場合と、このページの書き換え処理が30秒以内に完了しなかった場合などが考えられる)。ここでは、簡略化のため、”特願” が表示されたことを確認し、検索結果一覧の表示が完了(=次の操作の準備が完了)したものと考える。

7.検索結果一覧にて公報のリンクをクリック

次に、所望の公報番号のリンクをクリックする。これには、このオブジェクトobjIEの全てのAタグの中から、所望の公報番号をテキスト(outerHTML)として持っているAタグを見つけ、このAタグをクリックすればよい。この操作は、参考サイトに掲載されている通りで構わないので、次のようになる(このとき、変数patnumには、所望の公報番号が、この一覧表に表示されるのと全く同じ形式で代入されている)。実際には、一覧表の中に所望の公報が見つからない場合の処理も必要となるが、ここでは省略する。

Dim objtag As Object

For Each objtag In objIE.document.getElementsByTagName(“a”)
      If InStr(objtag.outerHTML, patnum) > 0 Then
            objtag.Click
            Exit For
      End If
Next

Set objtag = Nothing

テストした範囲ではほぼ問題なく動くようだが、たまに、目的のAタグを見つけられずに、この For~Next を素通りするケースもあるようなので、目的のAタグが見つかるまで、何度か繰り返すような処理を加えてみた。以下の例では、Aタグが見つかるまで最大30秒間、Do While~Loop を繰り返す。

Dim flag As Integer

flag = 0
i = 1
Do While flag = 0 AND i < 300
      For Each objtag In objIE.document.getElementsByTagName(“a”)
            If InStr(objtag.outerHTML, patnum) > 0 Then
                  objtag.Click
                  flag = 1
                  Exit For
            End If
      Next
      Application.Wait [Now()] + 100 / 86400000
      i = i + 1
Loop

Set objtag = Nothing

8.文献表示画面をオブジェクトとして取り込む

ここまでの操作によって、検索結果一覧表内の所望の公報のリンクをクリックすることで、新たなタブまたはウインドウで、下図のような特許・実用新案文献表示画面が表示される。(ただし、2.事前設定、(2) IEの設定、①のポップアップブロックの設定が正しく行われていないと、ここでIEのポップアップブロック機能が働いて、マクロがうまく動かなくなるので、必ず、事前に設定しておくことが必須である。)

この状態ではまだ、VBAから、この新たに表示されたページの操作はできない。操作するためには、このページをオブジェクトとして取り込む必要がある。この方法も、ネットを見ると色々と書かれているが、ここでは次のようなコードによって、変数 objIE2 に取り込む。

Dim objIE2 As InternetExplorer
Dim shl As Object
Dim win As Object
Dim targetTitle As String

flag = 0
i = 1
targetTitle = “特許・実用新案文献表示”

Do While flag = 0 And i < 300
      For Each win In shl.Windows
            DoEvents
            If win.Name = “Internet Explorer” Then
                  If InStr(win.document.title, targetTitle) > 0 Then
                        Set objIE2 = win
                        flag = 1
                        Exit For
                  End If
            End If
      Next
      Application.Wait [Now()] + 100 / 86400000
      i = i + 1
Loop

このうち、For~Next では、この時点で立ち上がっている全てのウインドウを調べ、それがInternet Explorer のウインドウであれば、そのタイトルを調べ、タイトルに “特許・実用新案文献表示” を含むものを探し出し、見つかったウインドウを変数objIE2に代入する、という処理を行っている。ここで、For~Next 全体が Do While~Loop に入っているのは、実際に操作してみると、目的のウインドウを見つけられずに、For~Next を素通りするケースがしばしばあることがわかったため、100ミリ秒の待ち時間を入れて、何度か繰り返すことで確実に取り込もうという趣旨である。ここで flag=0 のまま、Do While~Loop を抜けてくる場合には、何らかのエラー処理が必要となる。

ここまでで、文献表示画面を取り込むことができたので、次回は、文献表示画面を操作して、公報内容を取り込む方法について説明したい。

Excel VBAを使用してJ-PlatPatから公報テキストをダウンロードする方法(3)

4.J-PlatPatのトップページを開く

最初に、IEを立ち上げ、J-PlatPatのトップページを開く。この操作は、以下のように参考サイトの実例をそのまま真似て、URLだけを”https://www.j-platpat.inpit.go.jp”とすれば、特に問題ない。

Dim objIE As InternetExplorer
Dim url As String

Set objIE = CreateObject(“InternetExplorer.Application”)
objIE.Visible = True
url = “https://www.j-platpat.inpit.go.jp/”

objIE.Navigate2 url

Do While objIE.readyState <> 4 Or objIE.Busy
      DoEvents
Loop

これで、下図のように IE が起動し、J-PlatPatのトップページが開く。このとき、変数 objIE にこのページの情報がオブジェクトとして取り込まれる。最後の3行は、ページ内容の読み込みが完了するのを待つための、お約束みたいなもの。

ここで、読み込みが完了していないまま、次の操作(公報番号の入力や、検索ボタンのクリック)を行うと、エラーが出たり、操作を正しく受け付けてくれない。実際に動かしてみると、問題なく次の操作(公報番号の入力、検索ボタンのクリック)まで進むこともあるのだが、結構な確率で、次のようなエラーメッセージが出たり、

はたまた、(テキストボックスに公報番号を入力してからクリックしたはずなのに)下図のように「検索キーワードを入力してください。」といったメッセージが出てしまうことがある。

試しに、手動でステップ実行してみると、特にエラーが出たりすることはないので、どうやら連続実行すると、まだ完全に準備が整わないうちに次の操作が行われるために発生するエラーのようだ。ならば、次の操作に入る前に適当な待ち時間を入れてもいいのだが、サイトの状況やPCの状況によっても必要な待ち時間は変わるだろうし、不必要に長い待ち時間を入れるのも面白くない。

そこで、「次の操作の受付準備完了」≒「前の操作(表示)が完全に終了」と考え、次のように、「検索」ボタンが表示されていることを確認し、表示されていないときは表示されるのを待つ、という意図のコードを書いてみた。(このページ内に”検索”という語句は何度も出てきているが、document.body.innerHTMLを調べてみると、”>”と”<“で挟まれた”検索”は、検索ボタン②のところだけにしか存在していないようだ。)

Do While InStr(objIE.document.body.innerHTML, “>検索<“) = 0
      DoEvents
      Application.Wait [Now()] + 100 / 86400000
Loop

(※ 3行目は、100ミリ秒の時間待ち操作である)

その結果、テストした範囲では、先に出たようなエラーは全く出なくなった。実際に、Do While ~ Loopを何度回っているかを調べてみると、毎回異なるが0~5回程度となったので、このコードは有効に機能しているようだ。

このように、JavaScriptで書かれたページの読み込み完了を待つためには、お約束の objIE.readyStateやobjIE.Busyをチェックするだけではなく、確かにそのページの表示が完了したであろうことを確認してから次の操作に進む方法が有効となるようだ。

5.公報番号をテキストボックスに入力し、検索ボタンをクリック

次に、公報番号をテキストボックス(検索窓)に入力し、検索ボタンをクリックする。公報番号は、”特開2019-123456″、”特開平01-123456″、”特許6543210″などの形式で入力する。ここには、複数の公報番号の入力が可能で、10個以上の入力も可能なようだが、念のため最大10個ぐらいにしておくのが無難だと思われる。複数の公報番号を入力する場合、公報と公報の間はスペース区切りとする。なお、公報番号の入力形式が多少異なっていても、J-PlatPat側で正しく理解してくれる場合もあるが、ハイフンの後は6桁、特許番号は7桁等、J-PlatPatでの正式な形式にそろえておく方が、あとのVBAのコーディングが楽になる。

まず、ブラウザ等の機能を使用して、このページの要素を調査し、テキストボックス①と検索ボタン②の要素名(NameまたはID)を調べる。すると、テキストボックス①は、IDが”s01_srchCondtn_txtSimpleSearch”であり、検索ボタン②は、Nameが”s01_srchBtn_btnSearch”であることがわかった。

そこで、テキストボックス”s01_srchCondtn_txtSimpleSearch”に公報番号を入力し、検索ボタン”s01_srchBtn_btnSearch”をクリックすればよいはずだが、これがなかなかうまくいかない。実際に、下のようなコードを書いて実行してみると、テキストボックス①内には確かに入力した公報番号が表示され、一見うまくいったように見えているのだが、クリック後に「検索キーワードを入力してください。」というメッセージが出てしまう。

Dim patnum As String
patnum = “特開2018-010101”

objIE.document.getElementById(“s01_srchCondtn_txtSimpleSearch”).Value = patnum
objIE.document.getElementsByName(“s01_srchBtn_btnSearch”)(0).Click

ここで3行目を”○○.Value = patnum”の代わりに、”○○.innerText = patnum”に代えてみると、patnumはテキストボックス①内に、灰色で表示され、クリック後には先ほどと同じ「検索キーワードを入力してください。」というメッセージが出てしまう。

この問題を解決すべく、色々と調べたり、試したりしてみたのだが、どうしてもテキストボックスへの入力がうまくいかない。半ばあきらめかけていたのだが、たまたま、”○○.Value = patnum”の行と”○○.innerText = patnum”の行の両方を実行した後に検索ボタンのクリック操作をしてみたところ、何とこれがうまく動き、検索が実行されたのである!!(これは一体どういう理屈なのか、まったく理由は不明) その後、さらに色々とテストしてみた結果、テキストボックス①にフォーカスを当てた後に、innerTextで公報番号を入力する方法でもうまくいくことがわかった。ということで、最終的に、次のようなコードで、無事にテキストボックス①に公報番号を入力した後に、検索ボタン②をクリックして、検索を実行させることができるようになった。

objIE.document.getElementById(“s01_srchCondtn_txtSimpleSearch”).Focus
objIE.document.getElementById(“s01_srchCondtn_txtSimpleSearch”).innerText = patnum
objIE.document.getElementsByName(“s01_srchBtn_btnSearch”)(0).Click

Do While objIE.readyState <> 4 Or objIE.Busy
      DoEvents
Loop

実際のプログラムでは、動作をより確実に行うため、テキストボックスへのinnterTextの入力と検索ボタンのClickの実行との間に、100ミリ秒程度の待ち時間を入れているが、通常、この待ち時間はなくても問題なさそうである。

次回は、検索結果一覧表の目的の公報のリンクをクリックして、文献表示画面を表示し、書誌事項、要約、請求の範囲、詳細な説明などをダウンロードする操作について説明する。

Excel VBAを使用してJ-PlatPatから公報テキストをダウンロードする方法(2)

.参考サイト

ExcelのVBAでインターネットエクスプローラ(IE)を制御する方法については、ネット上に様々な参考サイトがある。今回対象となるサイト、特許情報プラットフォーム(J-PlatPat)はJavaScriptで動的に内容が書き換わるサイトであるため、ちょっとハードルが高いが、主として次のようなサイトを参考にさせていただくことで、ともかくも意図した通りに動くツールを作ることができた。これらのサイトがなければ、手も足も出なかったと思うので、本当に感謝したい。

(1)VBAのIE制御入門
VBAでIEを立ち上げ、情報を入力したり、リンクをクリックしたり、データをダウンロードしたり、といった基本操作の数々が非常によくまとまっていて、大変参考になる。

(2)VBAでIEを操作してJavaScriptで動作するWebページをスクレイピング
J-PlatPatのように、表示内容がJavaScriptで動的に書き換わるようなページをIEで操作する方法についてまとまっている。

(3)Excel VBAでInternet Explorerを操作してみよう(中編)
VBAで実際のサイトを操作する際の手順などが具体的に記載されていて参考となる。 

3.事前設定

J-PlatPatのサイトをIEで操作するためには、以下に示すいくつかの事前設定が必要となる。(1) はExcelのVBAでIEを制御するための設定であり、(2) はIEでJ-PlatPatを巡回するための設定である。

(1) ExcelのVBAへのライブラリの設定
・VBAの編集画面にて、「メニュー」→「ツール」→「参照設定」を選択
・「Microsoft HTML Object Library」と「Microsoft Internet Controls」の2つにチェックを付け、「OK」ボタンを押す。
※ 参考:VBAでIE制御するためのライブラリ追加(参照設定)

(2) IEの設定
①ポップアップブロックの設定

これは、J-PlatPatのサイトで、検索結果のリンクをクリックして、文献表示画面が新たなタブ(ウインドウ)で開くときに、下図の赤枠で囲ったような「ポップアップブロック」のメッセージ画面が出るのを回避するための設定である。


・IEを立ち上げ、「ツール」→「インターネットオプション」→「プライバシー」タブを開く
・「ポップアップブロックを有効にする」にチェックを入れ、「設定」ボタンをクリック
・「許可するWebサイトのアドレス」欄に “*.inpit.go.jp” と入力し、「追加」ボタンをクリックし、「閉じる」ボタンをクリック、さらに「OK」ボタンをクリックする。
※ 参考:Internet Explorer 11 で、ポップアップブロックを有効/無効に設定する方法

②スクリプトによる貼り付け処理の設定
これは、J-PlatPatのサイトで、文献表示画面において「URL」ボタンをクリックしたときに、下図のような「クリップボードへのアクセス許可」のメッセージが出るのを回避するための設定である。

・IEを立ち上げ、「ツール」→「インターネットオプション」→「セキュリティ」タブを開く
・「レベルのカスタマイズ」ボタンをクリックし、「スクリプトによる貼り付け処理の許可」の設定で「有効にする」にチェックを入れ、「OK」ボタンをクリック
・「このゾーンの設定を変更しますか」に「はい」をクリック、さらに「OK」ボタンをクリックする。
※ 参考:Internet Explorerで「クリップボードのアクセス許可」ダイアログを表示させなくする方法

以上で事前準備は完了したので、次回から実際にVBAでIEを制御し、J-PlatPatを操作する方法について記載する。