1.ログイン
前回に引き続き、HTMLソースをまだ見れないうちに自動操作を記述するケースです。
ページ中の1番目の入力欄(input type="text")は、XPathで"//input[@type='text'][1]"で手に入ります。2番目なら[2]です。
HTML.html
<form action="XXXXXXXX">
ユーザーID <input type="text" value="" /><br />
パスワード <input type="password" value="" /><br />
<input type="submit" value="ログイン" />
</form>
C#.cs
driver.FindElement(By.XPath("//input[@type='text'][1]")).SendKeys("abcde");
driver.FindElement(By.XPath("//input[@type='password'][1]")).SendKeys("fghij");
driver.FindElement(By.XPath("//input[@value='ログイン'] | //button[text()='ログイン']")).Click();
Java.java
driver.findElement(By.xpath("//input[@type='text'][1]")).sendKeys("abcde");
driver.findElement(By.xpath("//input[@type='password'][1]")).sendKeys("fghij");
driver.findElement(By.xpath("//input[@value='ログイン'] | //button[text()='ログイン']")).click();
Python.py
driver.find_element_by_xpath("//input[@type='text'][1]").send_keys("abcde")
driver.find_element_by_xpath("//input[@type='password'][1]").send_keys("fghij")
driver.find_element_by_xpath("//input[@value='ログイン'] | //button[text()='ログイン']").click()
2.テーブルなし登録画面(失敗)
下記のようなHTMLの場合に、「氏名」「住所」の「文字列の右」という指定をして、tableを含むかどうか分からない場合にも要素を取得できないかがんばったのですが、できませんでした。
//[contains(text(),'氏名')]
でformを見つけられ、
//[contains(text(),'氏名')]//input[@type='text']
で氏名の入力欄も見つけられますが、「住所」にそのまま置き換えてもだめで、
//[contains(text()[2],'住所')]
とする必要がある上に、これで手に入るのもformなので、結局inputにも[2]が必要になり、
//[contains(text()[2],'住所')]//input[@type='text'][2]
となります。
inputに[2]を指定するのであれば、
//*[contains(text()[2],'住所')]
自体が必要ありません。
また、tableを使用せずにform直書きと分かっていないとtext()に[2]を使えません。
HTML.html
<form action="XXXXXXXX">
氏名 <input type="text" name="name" value="" /><br />
住所 <input type="text" name="address" value="" /><br />
<input type="submit" value="登録" />
</form>
3.テーブルあり登録画面(途中経過)
上のHTMLだと見出しがずれるので使われないで、下記のようにtableが使われてtdでそれぞれ別になれば、
//[contains(text(),'氏名')]/..//input[@type='text']
でいけそうな気がしてきました。
上の記述だと、「氏名」の兄弟タグであれば左側のinputも取得してしまうので、さらに厳密にすると、
//[contains(text(),'氏名')]/following-sibling:://input[@type='text']
となります。
//[contains(text(),'氏名')]/following-sibling::[1]//input[@type='text']
で、次の兄弟タグのみになります。
//[contains(text(),'氏名')]/following-sibling::*//input[@type='text'][1]
で、次の兄弟タグに限らず、兄弟タグの中で最初のinput type="text"になります。
HTML.html
<form action="XXXXXXXX">
<table>
<tbody>
<tr><td>氏名</td><td><input type="text" name="name" /></td></tr>
<tr><td>住所</td><td><input type="text" name="address" /></td></tr>
<tr><td colspan="2"><input type="submit" value="登録" /></td></tr>
</tbody>
</table>
</form>
Python.py
driver.find_element_by_xpath("//*[contains(text(),'氏名')]/following-sibling::*//input[@type='text'][1]").send_keys("佐藤太郎")
driver.find_element_by_xpath("//*[contains(text(),'住所')]/following-sibling::*//input[@type='text'][1]").send_keys("東京都千代田区")
driver.find_element_by_xpath("//input[@value='登録'] | //button[text()='登録']").click()
HTMLが見れるようになれば、素直にname属性で探せばよいですが。
4.テーブルなし登録画面(リベンジ)(途中経過)
下記のXPathで見つけられました。
inputが階層下にある場合は未対応です。
HTML.html
<form action="XXXXXXXX">
氏名 <input type="text" name="name" value="" /><br />
住所 <input type="text" name="address" value="" /><br />
<input type="submit" value="登録" />
</form>
Python.py
driver.find_element_by_xpath("//text()[contains(.,'氏名')]/following-sibling::input[@type='text'][1]").send_keys("佐藤太郎")
driver.find_element_by_xpath("//text()[contains(.,'住所')]/following-sibling::input[@type='text'][1]").send_keys("東京都千代田区")
driver.find_element_by_xpath("//input[@value='登録'] | //button[text()='登録']").click()
同じXPathでテーブルなしとテーブルあり両方に対応したいですが、このXPathだとテーブルありのHTMLでは見つけられませんでした。
5.テーブルあり、テーブルなし両対応(途中経過)
単純に「|」で結合しました。
Python.py
driver.find_element_by_xpath("//*[contains(text(),'氏名')]/following-sibling::*//input[@type='text'][1] | //text()[contains(.,'氏名')]/following-sibling::input[@type='text'][1]").send_keys("佐藤太郎")
driver.find_element_by_xpath("//*[contains(text(),'住所')]/following-sibling::*//input[@type='text'][1] | //text()[contains(.,'住所')]/following-sibling::input[@type='text'][1]").send_keys("東京都千代田区")
driver.find_element_by_xpath("//input[@value='登録'] | //button[text()='登録']").click()
6. テーブルあり、テーブルなし(階層なし)、テーブルなし(階層下)全対応(最終形)
following-sibling::*//
と無駄なことをせずに、
following::
でいけました。
HTML.html
<form action="XXXXXXXX">
<table>
<tbody>
<tr><td>氏名</td><td><input type="text" name="name" /></td></tr>
<tr><td>住所</td><td><input type="text" name="address" /></td></tr>
<tr><td colspan="2"><input type="submit" value="登録" /></td></tr>
</tbody>
</table>
</form>
または
<form action="XXXXXXXX">
氏名 <input type="text" name="name" value="" /><br />
住所 <input type="text" name="address" value="" /><br />
<input type="submit" value="登録" />
</form>
または
<form action="XXXXXXXX">
氏名 <div><input type="text" name="name" value="" /></div><br />
住所 <div><input type="text" name="address" value="" /></div><br />
<input type="submit" value="登録" />
</form>
Python.py
driver.find_element_by_xpath("//text()[contains(.,'氏名')]/following::input[@type='text'][1]").send_keys("佐藤太郎")
driver.find_element_by_xpath("//text()[contains(.,'住所')]/following::input[@type='text'][1]").send_keys("東京都千代田区")
driver.find_element_by_xpath("//input[@value='登録'] | //button[text()='登録']").click()
↧