【selenium】テーブル内の文字列をXPathを用いて取得してみようという話【java】

こんにちはtsuttieです(*'▽')
XPathでテーブル内の文字列を出力するプログラムを作成したので紹介したいと思います。【java】


#1. Selenium2を使ってみた！
Webアプリのテスト自動化を目的としてSelenium2を使ったので詰まった点を数回に分けてまとめて行きたいと思います。
#2. 使用したSelenium
・Selenium IDE
・Selenium Webdriver (Java 3.5.0)
※導入方法についてはわかりやすくまとめていらっしゃる方が多くおりますので、そのあたりのお話は省きます。
#3. 【本題】テーブル内のテキストをXPathを用いて取得してみようという話
　今回は題名の通りXPathを用いてテーブル内のテキストを取得してみました。
　では、めちゃくちゃ簡単に以下のようなHTMLページを想定します。

| 番号|名前|年齢|好きな食べ物|
|:--|:--|:--|:--|
|1|マイク|15|チキンバー|
|2|クリス|21|さくらもち|
|3|太郎|48|ピッツァ|

    <table>
        <tr>
            <th>番号</th><th>名前</th><th>年齢</th><th>好きな食べ物</th>
        </tr>
        <tr>
            <td>1</td><td>マイク</td><td>15</td><td>チキンバー</td>
        </tr>
        <tr>
            <td>2</td><td>クリス</td><td>21</td><td>さくらもち</td>
        </tr>
        <tr>
            <td>3</td><td>太郎</td><td>48</td><td>ピッツァ</td>
        </tr>
    </table>

今回は、HTML内のboby内のform内に上のテーブルがあると想定します。
通常seleniumで何か指定をする場合、class名やidで指定をする場合が多いですが
こういったテーブルに何も指定がされておらず、またその中身を詳しく見たい時などにはXPathでの指定は良いかもしれません。(他にもたくさん使うことはたくさんあります。)
とはいっても実はかなり簡単でマイクを指定したい場合は

`html/body/form/table/tr[2]/td[2]`

としてあげれば問題ないかと思います。
htmlの中のbodyの中のformの中のtableの中のtr2行目のtdの2列目
といった解釈で大方間違いないかと思います。
イメージとしては住所的な感じ・・・？

では、このテーブルの行数不定だった場合の取得方法を考えます。
何かしらの検索を行い、テーブルの列の数は決まっているけど
行数は決まっていないものを想定した時に
必要になるのはもちろんテーブルの行数です。(当たり前・・・)
それを取得するのは以下になります。

`driver.findElement(By.xpath("html/body/form/table")).findElements(By.tagName("tr")).size();`

先ほどの要領でテーブルを指定してあげて、trの数を探してあげることで行数の指定が可能です。
これらを用いて、テーブルをSeleniumで取得するものを作成してみました。

```java:tableget.java

package ~;

import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;

public class tableget {

	private WebDriver driver;

	@Before
	public void setUp() throws Exception {
		//webdriverの設定
		System.setProperty("webdriver.gecko.driver", "./driver/geckodriver.exe");
		driver = new FirefoxDriver();
	}

	@After
	public void tearDown() throws Exception {
		driver.quit();
	}

	@Test
	public void test() throws Exception {

		//出力用txtの作成
		String Filename = "テスト.txt";
		File createfile = new File("./フォルダ名/" + Filename);
		createfile.createNewFile();
		FileWriter filewriter = new FileWriter(createfile);


			try {

                //ページまで移動
		        String URL = "https://www.hegehoge";
			    driver.get(URL);
			    Thread.sleep(500);

                //行数を取得
			    int row = driver.findElement(By.xpath("html/body/form/table")).findElements(By.tagName("tr")).size();

			    Thread.sleep(500);

                //row(行)の数だけ繰り返す。(1行目はthなので省く)
			    for(int i = 2; i <= row; i++)
			    {
			    	String xpath = "html/body/form/table/";
			    	
                    //XPath作成のためにiをstringへ変換
			    	String istring = String.valueOf(i);
			    	
			    	xp = xpath + "tr[" + istring + "]/";
			    	String replace = "";
			    	
			    	//例：xp = html/body/form/table/tr[2]/
			    	//列は4列構成なので1～4を取り出す
			    	for(int j = 1; j <= 4; j++)
			    	{
			    		String xpa = "";
			    		String val = "";
			    		String jstring = String.valueOf(k);
			    		replace = xp;
			    		xpa = replace + "td[" + jstring + "]";
			    		
			    		//例：xpa = html/body/form/table/tr[2]/td[1]
			    		//xpaの位置にあるテキストを取得して書き込む
			    		val = driver.findElement(By.xpath(xpa)).getText();
			    		filewriter.write(val);
			    		filewriter.write(" ");
			    		
			    		//コンソールへの書き出し
			    		System.out.println(val);
			    	}
			    	//1行分終わったら改行
			    	filewriter.write("\n");
			    }

			} catch (Exception e) {

			e.printStackTrace();
			filewriter.write(e.getMessage() + "\n");

		} finally {

			filewriter.close();

		}
	}
}

```
これで先ほどの例で示したテーブルの中身がもし動的に行数と値が変わっても取得することが可能です。
id指定ばかりでXPathあまり指定で使うことはなかったですが、テーブル相手になると使用必須になりそうですね。(まさかtdひとつひとつにidはふられていないでしょうし・・・)


#4. まとめ

今回はXPathについての記事となりました。
何かご指摘等ありましたら、コメントいただければ幸いです。
よろしくお願いします。('◇')ゞ


#5. 参考資料
[PythonでSeleniumを使ってWebページ内のテーブルの内容を取得する](http://www.k-hitorigoto.online/entry/2017/03/09/223538)