【初心者向け】Python+Selenium+ChromeDriver+shellで作業を自動化してみた②

プログラミング

さて、今回は前回に引き続き、Seleniumによる作業の自動化について、前回よりも手順を増やした自動化プログラムをご紹介していきます。

前回は「Google Chromeを自動的に開く」までの動作を自動化するプログラムを作成しましたが、

今回は、下記の動作をSeleniumで自動化していきたいと思います。

「Google Chromeを自動的に開く、検索BOXに入力する、検索ボタンをクリックする」

とても簡単ですので参考にしていただければと思います。

とにかく結論が欲しい方は目次の成功例の章をクリックしてジャンプしちゃっててください↓

自動的にGoogle Chromeを立ち上げる

まずは、ブラウザを立ち上げるところから始めましょう。
seleniumの環境構築からChromeをワンクリックで自動立ち上げまでの自動操作についての詳細は前回の記事を参照してください。

まずGoogle Chromeを立ち上げるためには、下記のコードをコピペしてください。
※executable_path=〜以降の部分はchromedriverが存在するファイルパスを指定してください。

# 必要なクラスのインポート
from selenium import webdriver
# chromedriverの場所を指定
driver = webdriver.Chrome(executable_path="/Users/ユーザ名/Desktop/chromedriver")
# googleのサイトを表示
driver.get("https://www.google.com/")

これでChromeが自動的に立ち上がります。

自動的に検索BOXに文字を入力する

次に文字の入力を自動化します。

結論から、、
下記のコードを加えると、seleniumが自動的に検索BOXに文字を入力してくれます。
※下記の場合は「Yahoo!JAPAN」と入力されます。

# 必要なクラスのインポート
from selenium.webdriver.common.by import By
# xpathの指定、文字入力
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input").send_keys("Yahoo!JAPAN") 

ここまでのソースを合体させると、次のようになります。

# 必要なクラスのインポート
from selenium import webdriver
from selenium.webdriver.common.by import By

# chromedriverの場所を指定
driver = webdriver.Chrome(executable_path="/Users/ユーザ名/Desktop/Python/chromedriver")
# googleのサイトを表示
driver.get("https://www.google.com/")
# xpathの指定、文字入力
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input").send_keys("Yahoo!JAPAN") 



上記の処理について解説していきます...

手順①:冒頭で要素取得の手段を判別するための「By」クラスをimportする。

# 必要なクラスのインポート
from selenium.webdriver.common.by import By

手順②:画面の要素をxpathで指定する(この場合、Googleの検索ボックスの要素のxpath)

# xpathの指定、文字入力
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input")

手順③:入力欄に任意の文字(下記の場合「Yahoo!JAPAN」)を入力する

# 入力する値を設定
.send_keys("Yahoo!JAPAN")


手順②のxpathの具体的な取得方法については下記の通りです。

1.画面上で取得したい要素の場所で右クリック
2.検証をクリック
3.「Copy full Xpath(完全なxpathを取得)」をクリック



画像を使って説明していきますね。


1.画面上で取得したい要素の場所で右クリック
2.検証をクリック

3.「Copy full Xpath(完全なxpathを取得)」をクリック

コピーしたxpathを貼ってみると以下のようになりました。

# xpathの値
/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input

このxpathを「(By.XPATH, "xxx")」のダブルクオーテーションの中に入れてあげればそのxpathの場所の要素を取得出来ます。

基本的には「要素の取得」+「〜する(入力するなど)」を組み合わせれば簡単に自動操作の処理を組むことができます。

※ただし、次に説明しますが画面が描画(ロードが完了)される前に要素を取得しようとするとエラーを起こすため、注意が必要です。

自動的に検索ボタンをクリックする

次に自動的に検索ボタンをクリックさせます。

結論から、、
下記のコードを加えると、画面上の「Google検索ボタン」を自動的にクリックしてくれます。

# xpathの指定、検索ボタンクリック
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[2]/div[2]/div[5]/center/input[1]").click() 

ここまでのソースを合体させると下記のようになります。
※注意
まだこのままだと上手く動きません!下の成功例まで読み進めてください!

# 必要なクラスのインポート
from selenium import webdriver
from selenium.webdriver.common.by import By

# chromedriverの場所を指定
driver = webdriver.Chrome(executable_path="/Users/ユーザ名/Desktop/Python/chromedriver")
# googleのサイトを表示
driver.get("https://www.google.com/")

# xpathの指定、文字入力
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input").send_keys("Yahoo!JAPAN") 

# xpathの指定、検索ボタンクリック
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[2]/div[2]/div[5]/center/input[1]").click()

こちらも要素の取得」+「クリックする」の組み合わせで簡単にできます。

失敗例(クリックされない)

上記の通りにxpathで指定してもボタンをクリックできませんでした。

手順としては次のとおりです。

まずは画面上の「Google検索」のボタンの要素をxpathで取得します。

「Google検索」ボタンの要素の上で右クリックし、検証をクリック

右側の検証ツールの検索ボタンの要素のxpathをコピー

コピーしたxpathを下記のようにソースに落とし込みます。

# xpathの指定、検索ボタンクリック
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[2]/div[2]/div[5]/center/input[1]").click() 

全体のソースは下記になります。

# 必要なクラスのインポート
from selenium import webdriver
from selenium.webdriver.common.by import By

# chromedriverの場所を指定
driver = webdriver.Chrome(executable_path="/Users/ユーザ名/Desktop/Python/chromedriver")
# googleのサイトを表示
driver.get("https://www.google.com/")

# xpathの指定、文字入力
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input").send_keys("Yahoo!JAPAN") 

# xpathの指定、検索ボタンクリック
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[2]/div[2]/div[5]/center/input[1]").click()

これで実行してみると、下記のエラーが出力されました。
どうやら指定した要素にアクセスできないようです。

selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable 
// 直訳:要素と対話できません。つまり、要素にアクセスできない。

なぜでしょうか?
次の章で解決していきましょう。

成功例(wait処理を入れたらクリックできた)

結論として、、
クリックや入力などの動作の直前に待機処理を加えることで解決しました。

成功したソース全体像は下記の通りです。(完成形)
「Google Chromeを自動的に開く、検索BOXに入力する、検索ボタンをクリックする」

# 必要なクラスのインポート
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# chromedriverの場所を指定
driver = webdriver.Chrome(executable_path="/Users/go/Desktop/Python/chromedriver")
# googleのサイトを表示
driver.get("https://www.google.com/")

# タイムアウト時間の設定(最大10秒待機)
wait = WebDriverWait(driver, 10)

# xpathの指定、文字入力
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input").send_keys("Yahoo!JAPAN")

# xpathの指定、待機処理
wait.until(EC.visibility_of_all_elements_located((By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[2]/div[2]/div[5]/center/input[1]"))) 

# xpathの指定、検索ボタンクリック
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[2]/div[2]/div[5]/center/input[1]").click()



詳しい処理について説明していきますね。
手順としては下記の通りです。
①ソースの冒頭に待機処理するためのクラスのimport文を入れる
②待機処理の変数waitの定義をする
③クリックする動作の直前に待機処理を加える
④「Google検索」ボタンをクリックする

①ソースの冒頭に待機処理するためのクラスのimport文を入れる

# 必要なクラスのインポート
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

②待機処理の変数waitの定義をする

# タイムアウト時間の設定(最大10秒待機)
wait = WebDriverWait(driver, 10)

③クリックする動作の直前に待機処理を加える

# xpathの指定、待機処理
wait.until(EC.visibility_of_all_elements_located((By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[2]/div[2]/div[5]/center/input[1]"))) 

④「Google検索」ボタンの要素を指定してクリックする処理を加える

# xpathの指定、検索ボタンクリック
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[2]/div[2]/div[5]/center/input[1]").click() 


手順③の「EC.visibility_of_all_elements_located」というメソッドは、指定した要素が表示されているかどうか判断してくれるものになります。
そのメソッド前に「wait.until」を付け加えることで、「指定した要素が表示されるまで待機」という意味になります。

ここまでの全体のソースは下記になります。(完成形)

# 必要なクラスのインポート
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# chromedriverの場所を指定
driver = webdriver.Chrome(executable_path="/Users/go/Desktop/Python/chromedriver")
# googleのサイトを表示
driver.get("https://www.google.com/")

# タイムアウト時間の設定(最大10秒待機)
wait = WebDriverWait(driver, 10)

# xpathの指定、文字入力
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input").send_keys("Yahoo!JAPAN")

# xpathの指定、待機処理
wait.until(EC.visibility_of_all_elements_located((By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[2]/div[2]/div[5]/center/input[1]"))) 

# xpathの指定、検索ボタンクリック
driver.find_element(By.XPATH, "/html/body/div[1]/div[3]/form/div[1]/div[1]/div[2]/div[2]/div[5]/center/input[1]").click()

このソースを動かしてみましょう。

成功しました!

まとめ

今回は前回の続きで、下記の動作を自動化するプログラムを作成しました。

①GoogleChromeの起動
②検索BOXに文字を入力
③検索ボタンをクリック

筆者も仕事でseleniumシナリオを作成する時によくエラーを起こすのですが、
よくあるエラーの原因として挙げられるのが、画面の要素を取得出来ないことに起因するものが多いです。
つまり、画面が完全にロードされる前に要素をクリックしようとしたりすると処理に画面が追いつかずエラーを起こすことがよくあるのです。
そんな時は先ほど説明したwaitを使った待機処理を使ってみてください。

では今回はここまでで、また続きで細かい自動操作についてもご紹介できたらいいなと思っています。

以上

コメント

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