Seleniumでサイトを巡回させたり、何かを入力したり。
プログラムで色々なサイトを回らせるわけですが、単発司令のものをループで走らせると、その都度新ウィンドウを開ける仕様なので、気づいたらものすごい数のウィンドウが画面を埋め尽くしたりしてました。
で、これはさすがにまずかろうというので、新規タブで開けるようにしてみたのですが、、、まあ、限度がありますよね。
数が多いと、タブを切り替えてどうにかするとかいうレベルじゃなくなるので。
というわけで、適宜タブを閉じて新規タブを開けて作業させる、みたいなことを検討してみました。
利用使途としては、例えばGoogleさんで検索結果の一覧を出しておきながら、違うタブで各検索順位のサイトを徘徊して、必要な情報を取っては戻る、みたいなことですね。
そこでのSeleniumプログラムは、検索一覧のタブは残しておきながら、徘徊先サイトは別タブでその都度開けては閉めるを繰り返す、という流れになります。
問題は、タブ名を自動では割り振ってくれない点と、Seleniumプログラムが見ているタブが視覚的に見えるタブと違う点。
それぞれ、プログラム上でその都度具体的に指示してあげないとうまく動いてくれないのですね。
まず、タブ名の割り振りの件。
自動では割り振られないので、指示を出します。
「driver.window_handles」を使うことで、タブに番号が振られます。
list型の配列になります。
なので、
driver.window_handles[0] と書くと最初のタブ、
driver.window_handles[1] と書くとその次のタブが呼び出されることになります。
それじゃあ、ということで、
tabs = driver.window_handles
とかおいて使いまわそうとしたのですが、格納するのはその時点のウィンドウ/タブだけなんですね。
tabs = driver.window_handles # tab_0 tabs[0] = driver.get('https://www.google.com/search?q=あああ') # tab_1 driver.execute_script("window.open('');") driver.switch_to.window(tabs[1]) tabs[1] = driver.get('https://www.google.com/search?q=いいい')
こうすると、8行目「driver.switch_to.window(tabs[1])」のところで、
IndexError: list index out of range
リストからはみ出してるやんけ、と言われるのです。
対処としては、面倒なのですが新しいウィンドウ・タブを開けるたびに「driver.window_handles」を振り直すか、もう初めから置き換えるのは諦めるか、です。
具体的には、tabs[1]を使わず、driver.window_handles[1]とするか、
新規タブを開くたびに呪文のように、
tabs = driver.window_handles
と振り直すか、ですね。
次、閉じたタブがまだ操作対象になっている件。
タブを閉じて元のタブに戻ってそこでまた指示を出すという場合、閉じただけではプログラム上は操作対象のタブは切り替わっていません。
driver.close() tabs[0] = driver.get('https://www.google.com/search?q=ううう')
とすると、
no such window: target window already closed
そのウィンドウもう閉じてまっせ、と言われます。
閉じたら、対象タブも動かさないといけません。
上記の2文の間に、
driver.switch_to.window(tabs[0])
を突っ込んであげます。
この場合は、リストの中のウィンドウ/タブが増えたわけじゃないので、改めて番号を振り直さないでも文句言わずに稼働してくれます。
というわけで
# tab_0 tabs = driver.window_handles tabs[0] = driver.get('https://www.google.com/search?q=あああ') # tab_1 driver.execute_script("window.open('');") tabs = driver.window_handles driver.switch_to.window(tabs[1]) tabs[1] = driver.get('https://www.google.com/search?q=いいい') # tab_1を閉じ、tab_0 に戻ってゴニョゴニョ。 driver.close() driver.switch_to.window(tabs[0]) tabs[0] = driver.get('https://www.google.com/search?q=ううう')
こんな感じで。
1枚めのタブを開くときの番号振りは冗長なので、2,3行目は単に
driver.get('https://www.google.com/search?q=あああ')
だけでも問題ないですけどね。