Django Girls and Boys 備忘録

Python、Selenium、Django、java、iPhoneアプリ、Excelマクロなどで気付いたこと、覚えておきたいことなどを載せていきます。

【Python Selenium】新規ウインドウ(新規タブ)追加時のウインドウ切替方法(追加ハンドルをハンドル差異比較にて取得)


以下のような過去記事でウインドウの切替方法の1例などを記載しました。

 

kuku81kuku81.hatenablog.com

 

 

この中で、新規ウインドウが追加になった時に、新しいウインドウハンドルは必ずしもブラウザのドライバのハンドル(window_handles)の末尾に追加されるわけではないというようなことを記載しました。

 

実際に自分でウインドウ追加などをやりながらwindow_handlesを見ていたところでは、ハンドル数が1から2に増える場合には末尾に追加がほとんどだったのですが、ハンドルの数が増えてくると末尾でないところに追加される場合が多くなるような感じでした。

 

そのような場合に、新規ウインドウへの切替を行うには、新規ウインドウ追加前と追加後でwindow_handlesを比較して、追加後に追加されたハンドルを探し出してそのハンドルへの切替をする必要が出てきます。

 

そういう必要性があった時に、実際にハンドルの比較、抜き出しを行いましたので、備忘録もかねて書き残しておきます。

 

 

目次

 

 

プログラム自体はあまりいい書き方でないところもあるかと思います。

そこはご容赦ください。

 

実際に記載したプログラムの抜粋は以下のようになります。

 

ハンドルを比較し地道にがんばった方法

 

from selenium import webdriver
import os

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome import service as fs

######################################################################
path_driver = os.getcwd()+'\msedgedriver.exe'
# ドライバー指定でEdgeブラウザを開く
edge_service = fs.Service(executable_path=path_driver)
driver = webdriver.Edge(service=edge_service)
######################################################################
before_handles = driver.window_handles
before_len = len(driver.window_handles)

# 新しいタブを作成する(switch_to.new_window("tab")で新タブ追加)
# 新しいタブを作成し、フォーカスする
driver.switch_to.new_window("tab")

WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) > before_len)

# 新しいタブに切り替える(before_handlesとafter_handlesを比較、追加されたhandleにitch_to.windowで切り替える)

newhandle = driver.window_handles[-1]
after_handles = driver.window_handles
for ahandle in after_handles:
    flg = 0
    for bhandle in before_handles:
        if ahandle == bhandle:
            flg = 1
            break
    if flg == 0:
        newhandle = ahandle
        break
driver.switch_to.window(newhandle)

driver.get('https://www.google.com/')

 

はじめの4行は必要なライブラリのインポート文です。

 

次の3行でEdge用ですが、ドライバーの設定をしています。

 

次からが今回の内容ですが、

before_handles = driver.window_handles

before_len = len(driver.window_handles)

で、新規ウインドウ追加前のハンドルとその数を取得しています。

 

続いて、

driver.switch_to.new_window("tab")

で、新規ウインドウ(この例ではタブが追加)が追加されます。

 

次の、

WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) > before_len)

で、追加前のハンドル数(before_len)と追加後のハンドル数(lambda d: len(d.window_handles))を比較しています。

追加後のハンドル数が追加前のハンドル数より多くなるまで最大10秒間待機します。

 

newhandle = driver.window_handles[-1]

は、初期値として末尾のハンドルを入れているだけです。

 

after_handles = driver.window_handles

にて、新規ウインドウ追加後のハンドルを取得しています。

 

それに続く、

for ahandle in after_handles:

 flg = 0

 for bhandle in before_handles:

  if ahandle == bhandle:

   flg = 1

   break

 if flg == 0:

  newhandle = ahandle break

 

で、追加前ハンドル(before_handles)と追加後ハンドル(after_handles)を比較して、追加後ハンドルの中で、追加前ハンドルにないものがあれば、それを新しいハンドル(newhandle)に入れています。

 

driver.switch_to.window(newhandle)

で、その新しいハンドルに移動しています。

 

その後、

driver.get('https://www.google.com/')

とすることで、新規タブにGoogle検索ウインドウが表示されると思います。

 

 

ここまで、やってきていろいろと調べているうちに同内容を簡単に実施できそうな方法をみつけましたので追加で記載しておきます。

 

簡潔コードによる方法

 

from selenium import webdriver
import os

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome import service as fs

######################################################################
path_driver = os.getcwd()+'\msedgedriver.exe'
# ドライバー指定でEdgeブラウザを開く
edge_service = fs.Service(executable_path=path_driver)
driver = webdriver.Edge(service=edge_service)
######################################################################
before_handles = driver.window_handles
before_len = len(driver.window_handles)

# 新しいタブを作成する(switch_to.new_window("tab")で新タブ追加)
# 新しいタブを作成し、フォーカスする
driver.switch_to.new_window("tab")

WebDriverWait(driver, 10).until(lambda d: len(d.window_handles) > before_len)

# 新しいタブに切り替える(before_handlesとafter_handlesを比較、追加されたhandleにitch_to.windowで切り替える)

after_handles = driver.window_handles

# ウインドウハンドルの比較を行い、新規で開いたウインドウのハンドルを取得
newhandle = set(after_handles).difference(set(before_handles)).pop() driver.switch_to.window(newhandle) driver.get('https://www.google.com/')

 

最初のコードとの差異は、after_handles 取得後のfor文で地道にハンドルの差異を見つけていることが、

newhandle = set(after_handles).difference(set(before_handles)).pop()

の1行でできるということです。

 

実際に実行してみると、1つ目のプログラムと同様に2つ目の新規タブにGoogle検索ウインドウが表示されました。

 

関連記事:

【PythonからWeb操作】seleniumのインストール手順 - Django Girls and Boys 備忘録

 

【PythonによるExcelファイルの読み書き】PythonのダウンロードからExcelファイルの読み書きまでの一通りすべての方法 - Django Girls and Boys 備忘録

 

【PythonでのExcelファイル読み書き方法】ファイルオープンしているファイル(アクティブファイル)への書込方法 - Django Girls and Boys 備忘録

 

【Python Selenium】Webサイトのスクレイピングなどで必要なフレーム間移動方法 - Django Girls and Boys 備忘録

 

【Python Selenium】ブラウザ用ドライバーのダウンロードとインストール - Django Girls and Boys 備忘録

 

【PythonからWeb操作】selenium、各ブラウザ用ドライバーの最新バージョン確認、ダウンロード場所 - Django Girls and Boys 備忘録

 

【Python Selenium】新規ウインドウ追加時のウインドウ切替方法 - Django Girls and Boys 備忘録

 

【Python Selenium】ウインドウ表示時などでのWaitの方法、待機方法 - Django Girls and Boys 備忘録

 

【Python Selenium】新規ウインドウ(新規タブ)追加時のウインドウ切替方法(追加ハンドルをハンドル差異比較にて取得) - Django Girls and Boys 備忘録

 

【python】実行時に表示されるコンソールウインドウを非表示にする方法 - Django Girls and Boys 備忘録