ブラウザ操作してますか?
毎日同じブラウザ操作してませんか?
そんなブラウザ操作はSeleniumに任せましょう!
ブラウザを触っているときにリンクをCtrlを押しながらクリックして新しいタブで開くことありませんか?
僕はとてもよくやりますw
そんな一連の流れになります。
リンクを新しいタブで開いて移動
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
import platform
import sys
driver = webdriver.Chrome("chromedriver.exe") #chromedriver.exe読み込み
#
#
# 該当ページまでの処理
#
#
# クリックする要素
element = driver.find_element_by_xpath('/html/body/hogehoge')
# element = driver.find_element_by_link_text("hogehoge") #リンクテキストで取得したい時はこちら
# クリック前のハンドルリスト
handles_befor = driver.window_handles
# (リンク)要素を新しいタブで開く
actions = ActionChains(driver)
if platform.system() == 'Darwin':
#Macなのでコマンドキー
actions.key_down(Keys.COMMAND)
else:
#Mac以外なのでコントロールキー
actions.key_down(Keys.CONTROL)
actions.click(element)
actions.perform()
# 新しいタブが開ききるまで最大30秒待機
try:
WebDriverWait(driver, 30).until(lambda a: len(a.window_handles) > len(handles_befor))
except TimeoutException:
print('TimeoutException: 新規ウィンドウが開かずタイムアウトしました')
sys.exit(1)
# クリック後のハンドルリスト
handles_after = driver.window_handles
# ハンドルリストの差分
handle_new = list(set(handles_after) - set(handles_befor))
# 新しいタブに移動
driver.switch_to.window(handle_new[0])
負荷がかかりすぎないように気をつけて
適宜wait
やsleep
を入れましょうー
解説
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
Seleniumライブラリと今回必要なパッケージを読み込みます。
import platform
import sys
OSを判断する為のライブラリを読み込みます。
エラーが発生した際に終了する為のライブラリを読み込みます。
driver = webdriver.Chrome("chromedriver.exe") #chromedriver.exe読み込み
#
#
# 該当ページまでの処理
#
#
chromedriverを起動して操作しましょう。
# クリックする要素
element = driver.find_element_by_xpath('/html/body/hogehoge')
# element = driver.find_element_by_link_text("hogehoge") #リンクテキストで取得したい時はこちら
xpath
やlink_text
でクリックする要素を変数に代入しましょう。
# クリック前のハンドルリスト
handles_befor = driver.window_handles
新しいタブが開く前のハンドルをリスト形式で取得します。
# (リンク)要素を新しいタブで開く
actions = ActionChains(driver)
if platform.system() == 'Darwin':
#Macなのでコマンドキー
actions.key_down(Keys.COMMAND)
else:
#Mac以外なのでコントロールキー
actions.key_down(Keys.CONTROL)
actions.click(element)
actions.perform()
ActionChains
というクラスを使うとキー操作を記録して実行することができます。
Macとそれ以外のOSではGoogle Chromeブラウザの場合、新しいタブで開くショートカットキーが異なります。
Mac : command + クリック
WindowsやLinux : Ctrl + クリック
platformライブラリでOSを判断して条件分岐させています。
actions.perform()
で記録したキー操作が実行されます。
# 新しいタブが開ききるまで最大30秒待機
try:
WebDriverWait(driver, 30).until(lambda a: len(a.window_handles) > len(handles_befor))
except TimeoutException:
print('TimeoutException: 新規ウィンドウが開かずタイムアウトしました')
sys.exit(1)
新しいタブが開いた時に時間がかかることがあるので待機させます。
WebDriverWait(driver, 30)).until
ではdriverを最大30秒待機するようにします。
lambda a: len(driver.window_handles) > len(handles_befor)
ではラムダ式を使用して一行で記載しています。
len(handles_befor)
新しいタブで開く前のハンドル数より
len(a.window_handles)
新しいタブが開いた瞬間のハンドル数が上回ったら待機が解除されます。
try
を使ってエラーが出たらログにエラーを出力してシステムを終了しています。
# クリック後のハンドルリスト
handles_after = driver.window_handles
新しいタブが開いた後のハンドルをリスト形式で取得します。
# ハンドルリストの差分
handle_new = list(set(handles_after) - set(handles_befor))
リストをset
に変換した後に-
で引き算のようにすると差分を取得することができます。
それを変数に代入しています。
# 新しいタブに移動
driver.switch_to.window(handle_new[0])
差分となったhandle_new[0]
が新しいタブのハンドルになるのでswitch_to.window
で移動します。
おまけ
タブを開きすぎて訳がわからなくなってもいつでも戻れるように
(そんなことにはならないようにしましょうw)
事前にカレントハンドルを取得しておくといいかもしれません。
# カレントウインドウ(タブ)のハンドルを代入
current_handle = driver.current_window_handle
#
#
# 処理
#
#
# カレントウインドウ(タブ)に移動
driver.switch_to.window(current_handle)
ありがとうございました!