【selenium×ExcelVBA】ウインドウ、タブを切り替える

お知らせ記事には広告が含まれておりますがExcelのスキルUPに繋がる様コンテンツ自体は手を抜かずに作成しております

名前指定でウインドウ(タブ)を切替える事ができる

スクレイピング中にリンクをクリックすると別のURLが表示されます。

同じウインドウの中でURLの情報だけが切り替わればそのままスクレイピング続行となります。

しかし別のURLを展開する際は必ず別ウインドウで起動するという仕様になっている事もあります。

よって操作側では通常はウインドウの開閉をコントロールするのは難しいです。

(参考:Ctrl+リンクをクリックすると必ず別ウインドウに指定のURLを展開する事ができます)

  • クリックなどのイベントによって表示されたウインドウにある要素を使いたい
  • 隠れてしまったウインドウにある要素も使いたい

このようにどのウインドウでスクレイピングを継続するのかはその時の流れによります。

ケースによって制御対象のウインドウをつかめるようにしておきたいものです。

EnjoyExcel
EnjoyExcel

Seleniumではウインドウのタイトルを指定する事で欲しいウインドウを掴むことができます

比較的簡単なコードです。すぐ使えるコードですので是非使ってみてください。

この本で勉強しました

Seleniumbasic(セレニウムベーシック)について最初に勉強した本です。

Seleniumの本はよくあるのですがSeleniumbasicについて解説されている本は非常に少ないです。

Seleniumについて勉強することができます

Seleniumbasicに関する記事は20ページほどしか無いですが十分勉強になります。

一般的に売られている本とは見た目も内容も一線を画すものになっていますよ。

電子書籍はこちらになります。

関連記事

後程紹介するコードではリンクをクリックするというコードを使っています。

クリックだけでも色々な種類があります。右クリックも再現可能です。

ウインドウを切り替えた後で画面の最大化を行うとよりスクレイピングでエラーが出にくくなります。

複数のウインドウから1つのウインドウを選択(定義)する理由

「各URLの要素はウインドウに紐付いているから」です。

Selenium側から見るとウインドウが複数展開されているとどのウインドウから情報を取得するのか分かりません。

Q
スクレイピン時に複数のウインドウ扱う際に個別にウインドウを定義する理由
A

各URLの情報は各ウインドウを定義してから取得する必要がある為

ウインドウが1つの時は定義しなくて良いです。定義しなくてもウインドウが指定出来ているからです。

しかしウインドウが2つ以上画面に居る時はどちらのウインドウに対して操作をするのか指示が必要です。

具体例

ウインドウAでスクレイピング中にリンクをクリックした際別ウインドウが立ち上がったとしましょう。

立ち上がったウインドウをBとします。ウインドウBは最前面に配置されたとします。

この時ウインドウBはアクティブになっていますがあくまで「最前面に配置されているだけ」です。

この状態では依然としてWebドライバーはウインドウAを選択しています。

ウインドウBでスクレイピングを継続するにはWebドライバーに指示を出す必要があります。

操作対象を特定する必要がある

アクティブ状態のウインドウ=操作対象のウインドウではないという事です。

よって作業対象のウインドウを切り替えたい時は都度指示が必要です。

コードを含めた作業内容を紹介

先に作業内容を紹介します。その後コード、コードの解説と続きます。

作業内容

私のブログの記事一覧からある記事のリンクをクリックします。

その後記事内のh2タグのテキストをイミディエイトウィンドウに出力するという作業になります。

リンク先URLのタイトル画像のすぐ下にある文字です。(画像下部赤枠参照)

【VBA×selenium×JS】任意の要素まで簡単にスクロール という記事のタイトル下のh2タグの文字列を取得します

アウトプット

コード実行後のVBEです。

イミディエイトウィンドウには文字が入っています。(画像下部赤枠参照)

イミディエイトウィンドウに文字列を表示させる
イミディエイトウィンドウにh2タグの文字列を取得できました

コード全体

今回使用したコードです。オレンジ色のボタンを押すことでコードがコピーされます。

ご自身のVBEに貼ってから以降の解説をご覧ください。

お願い

記事を追加、修正するとXPathが変わるので用意されているコードでエラーが発生する事があります。

その際はXPathを取り直していただきます様お願いします。

Sub windowを選択する()
 
'変数の定義
Dim Driver As New ChromeDriver  'ドライバーはChromeを選択
 
With Driver

    '1_ブラウザを起動後指定のURLにアクセス
    .Start "chrome"
    .Get "https://www.slt-pgming-21.net/2022-02-21-123000/"
    .Window.Maximize
     
    .Wait 1000
    
    '2_画面スクロール
    .ExecuteScript "return document.querySelector('#toc4')." _
    & "scrollIntoView ({behavior:'smooth' ,block:'start' })"

    
    .Wait 2000
    
    '3_指定の記事のリンクをクリック
    .FindElementByXPath("/html/body/div[1]/div[3]/div/main/" _
    & "article/div/ul[2]/li[8]/a").Click
                                 
    .Wait 1000
    
    '4_新規ウインドウをつかむ
    .SwitchToWindowByTitle _
    ("【VBA×selenium×JS】任意の要素まで簡単にスクロール | EnjoyExcel")
    
    .Wait 1000
    
    '5_h2タグの情報をイミディエイトウィンドウに書き出す
    Debug.Print .FindElementByXPath _
    ("/html/body/div[1]/div[3]/div/main/article/div/h2[1]/span").Text
    
End With
 
End Sub

構成

やっている事は5つです。

コードの構成
  • 1
    ブラウザを起動後指定のURLにアクセス
  • 2
    画面スクロール
  • 3
    指定の記事のリンクをクリック
  • 4
    新規ウインドウをつかむ
  • 5
    h2タグの情報をイミディエイトウィンドウに書き出す

解説

コードの構成に沿って解説します。

1_ブラウザを起動後指定のURLにアクセス

Chromeドライバーを選択して指定のURLにアクセスします。Getメソッドを使っています。

詳細知りたい方はこちらの記事を参照ください。

参考VBA×Selenium×ChromeでWebスクレイピング|nameタグを使う

2_画面スクロール

Javascriptを使っています。詳細知りたい方はこちらの記事を参照ください。

参考【VBA×selenium×JS】任意の要素まで簡単にスクロール

3_指定の記事のリンクをクリック

1つ前で紹介した画面スクロールの記事へのリンクをクリックしています。

FindElementByXPathメソッドを使っています。詳細知りたい方はこちらの記事を参照ください。

参考VBA×Chrome/Edgeでスクレイピング|XPathとは?|動画で解説

4_新規ウインドウをつかむ

Chromeドライバークラス内のSwitchToWindowByTitleメソッドを使います。

リンク先URLの記事タイトルを引数に指定しましょう。

引数はStringですのでダブルクォーテーションで挟む事を忘れない様にしてください。

ウインドウオブジェクト(クラス)を戻り値として返してきます。

ご注意ください

引数Titleはタブ内全ての文字を指定しましょう。変数や&(アンパサンド)も使えます。

引数として用意するタイトルは省略できません。省略するとエラーが出ます。

タイトルを取得する方法

タイトルが長くタブに映り切らない時はタイトルを取得し確認しましょう。コードはこちらです。

記事のタイトルを取得するコード(Chrome)

String型の変数 = ChromeDriver.Window.Title

別のプロシージャを用意しリンク先にアクセスして上のコードを使ってタイトルを取得しましょう。

取得したタイトルはコピーしてそのままSwitchToWindowByTitleメソッドの引数に使えます。

Titleプロパティから文字列を取り出す際の注意点

使用する際は変数で文字列を受けるようにコードを書くかDebug.Printを使用してください。

取得する文字列を受ける体制が出来てないとエラーになります。ご注意ください。

5_h2タグの情報をイミディエイトウィンドウに書き出す

ここもXPathを使っています。

4番のコードが無いとウインドウフォーカスが切り替わりません。

よってコードの10行目で最初にアクセスしたURLの情報を取得してしまいます。

4番のコードでウインドウを切り替えた結果リンク先のURLの情報が取得できている事を確認しましょう。

補足情報

4番の解説で使った画像の中に2つのメソッドが映っています。

  • SwitchToNextWindowメソッド
  • SwitchToPreviousWindowメソッド

SwitchToNextWindowメソッドで追加されたウインドウにフォーカスが移ります。(右のタブ)

SwitchToPreviousWindowメソッドで1つ前のウインドウにフォーカスが移ります。(左のタブ)

引数無しで使えるメソッドです。非常に使いやすいです。

SwitchToWindowByTitleメソッドを使わなくてもこれらのメソッドだけでも十分戦力になります

まとめ

これでスクレイピングしたいウィンドウを自分のタイミングでつかめるようになりました。

スクレイピングをする前まではアクティブな画面にフォーカスが向いていると決めつけていました。

今までどのウィンドウにフォーカスが向いているのかなんて考えた事も無かったです。

Excelシートは基本的にシートを指定しなければアクティブになっているシートに命令が入ります。

よってWebブラウザのウインドウも同じかと思っていましたが甘かったです。

VBAでもオブジェクト変数を使ってシートやブックを変数に格納しますね。

同じようにウィンドウを指定して使えばアクティブじゃなくても情報が取得できる事が分かりました。

オブジェクト変数について知りたい方は以下記事をご覧ください。

EnjoyExcel

タイトルとURLをコピーしました