前回は、Seleniumを使ってPythonでWebページを表示してみました。
今回は、テキストボックスに値を入力し、計算された結果を取得してみたいと思います。
目次
今回の課題
今回の課題は、
-
当サイトの「空気の物性値」のページにアクセスする。
-
温度のテキストボックスに値を入力する。
-
密度のテキストボックスの値を取得する。
の操作の自動化です。これをSeleniumを使ってPythonで実行してみます。
HTMLの知識
Seleniumを使ってWebブラウザを操作するためには、HTMLの知識が多少必要になります。
HTMLとは、ブラウザにホームページなどを表示させるためのテキスト文書です。Webブラウザは、HTMLを解読してページを表示しています。このページもHTMLで記述されています。HTMLの内容は簡単に見ることができます。今、
[Ctrl] + [U]
とキーボードを打ってください([Ctrl]キーと[U]キーを同時に)。すると、次のようなページが開かれると思います。
もともとホームページを作るときは、このようなHTML文書を記述します。これをブラウザは解読してページとして表示しているわけです。なお、この文書をHTMLソースと呼びます。
HTMLは、
<title>科学技術計算講座</title>
のように、タグとよばれる < > 記号で囲まれた記述になっています。上記の例だと、<title>と</title>に挟まれた文がページのタイトルとして認識されます。このようにタグで記述された部分はHTML要素と呼ばれます。
HTML要素の確認
では、「空気の物性値」のページを開いてください。このページも当然HTMLで書かれています。
ここでは、温度を入力するためのテキストボックスがあります。
このような要素もタグで記述されていますが、この記述部分をHTMLソースから探します。文字などから目でみて探してもいいのですが、ソースの量が多いと大変なので、ブラウザの機能を使って探してみます。
通常のページを表示させた状態で、
[Ctrl] + [Shift] + I
とキーボードで打ってください(3つ同時に)。すると、デベロッパーツールが開きます。ここで、下図のように左上にあるアイコンをクリックして、調べたい要素をページ上でクリックすると、
図のように、コンソールにそのHTMLタグが表示されます。
温度の入力ボックスは、
<input type="number" name="temp" style="width:200px;" value="20.0" onkeyup="propAirCalc()">
のようになっています。<input type="number" ***>は、数値を入力するためのテキストボックスを表します。ここで、name="temp"はこの要素につけられた名前です。styleは要素の大きさなどを指定するもので、valueはデフォルトで入力される値、onkeyupは値が入力されたら実行されるプログラムを表しています。
ここで必要なのは、nameの値 "temp" です。これはSeleniumでこの要素を識別するときに必要になるので覚えておきます。
ついでに、密度のテキストボックスも同様に確認しておきます。
<input type="text" name="den" style="width:200px;background-color:#bfffff;">
これもnameの値 "den" を覚えておきましょう。
Pythonプログラム
準備ができたので、PythonでWeb操作をするプログラムを作ってみます。プログラム全体を載せておきます。
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
import time
# webdriver
driver = webdriver.Chrome("./chromedriver.exe")
driver.get("https://cattech-lab.com/science-tools/properties-air/")
# wait
wait = WebDriverWait(driver, 30)
wait.until(EC.presence_of_all_elements_located)
# input temperature
input_temp = driver.find_element(By.NAME, "temp")
input_temp.clear()
input_temp.send_keys("30")
time.sleep(1)
# output density
output_den = driver.find_element(By.NAME, "den")
den = output_den.get_attribute("value")
print("Density ", den)
# close driver
driver.quit()
まず、冒頭のインポート部分ですが、Seleniumでいくつか処理が増えるので、前回より少し追加しています。
次のwebdriverの部分は、該当するページのURLを入力しています。
待機処理
# wait
wait = WebDriverWait(driver, 30)
wait.until(EC.presence_of_all_elements_located)
Webページを表示する時には、ブラウザがサーバーから送られるHTMLソースを読み取って表示するまでに、いくらか時間がかかります。一方で、Pythonプログラムの処理はどんどん進んでいくため、ページの表示を待ってから次の処理に進む必要があります。この待機処理を行う箇所がこの部分です。
wait.until(EC.presence_of_all_elements_located)は、「ページ内の全ての要素が表示されるまで待つ」という命令です。ただし、WebDriverWaitで指定した秒数(ここでは30秒)でタイムアウトとなりエラーを返します。
温度の入力
# input temperature
input_temp = driver.find_element(By.NAME, "temp")
input_temp.clear()
input_temp.send_keys("30")
time.sleep(1)
次に温度をテキストボックスに入力します。ここでは入力値を30[℃]とします。
driver.find_element(By.NAME, "temp")は、HTML要素を見つけるメソッドで、By.NAMEはHTML要素のnameで識別することを意味します。温度の入力ボックスのnameである"temp"を指定します。見つけた要素をinput_tempという変数に入れています。
input_temp.clear()は、すでにボックスに入力されている値を消去する命令です。
input_temp.send_keys("30")は、ボックスに 「30」を入力するという命令です。これで、あらかじめ入っていた20が消去され、30が入力されることになります。
time.sleep(1)は、処理を1秒待機させています。このページでは、温度の入力ボックスに値が入力されると、物性値計算のプログラムが呼び出され、計算された結果が出力ボックスに表示されます。プログラムは瞬時に終わりますが、念の為1秒待っています。
密度の取得
# output density
output_den = driver.find_element(By.NAME, "den")
den = output_den.get_attribute("value")
print("Density ", den)
次に結果として表示されている密度の値を取得します。
driver.find_element(By.NAME, "den")は、先程と同じように、密度のテキストボックスのnameを指定し、output_den変数にそのHTML要素を入れます。(ちなみに、タグはnameだけでなくidという識別値を持っている場合があります。この場合は、By.IDで識別できます。)
output_den.get_attribute("value")は、その要素のvalueの値を取得するという命令です。つまり、表示されている密度の値を取得して、denという変数に代入しています。
print("Density ", den)は、取得した値を標準出力に出力しています。
プログラムの実行
では作成したプログラムを実行してみてください。
ブラウザが起動してページが表示され、温度が20から30に書き換わる様子がわかると思います。
また、実行したプロンプトには、
Density 1.1648607
と表示され、温度30[℃]のときの密度の値が取得できました。
まとめ
今回は、PythonからWebブラウザのテキストボックスの値を書き換えて、計算結果を取得してみました。簡単な例でしたが、Webブラウザを人間が手で操作しなくても、値を入力したり結果を取得したりすることが自動でできることがわかったと思います。
次回は、この応用として入力値を連続して変化させて、結果をグラフ表示してみたいと思います。