ブラウザ自動操作の最近のブログ記事

前回、最後にちらっと書いたiMacrosを使ってみます。

ログイン、初回検索、2回目以降検索の3つのマクロを用意します。

login.iim (ログイン用マクロ)
VERSION BUILD=8961227 RECORDER=FX
URL GOTO=https://websearch.rakuten.co.jp/login.html
SET !ENCRYPTION NO
TAG POS=1 TYPE=INPUT:TEXT FORM=NAME:LoginForm ATTR=ID:loginInner CONTENT={{!VAR2}}
TAG POS=1 TYPE=INPUT:PASSWORD FORM=NAME:LoginForm ATTR=ID:loginInner CONTENT={{!VAR3}}
TAG POS=1 TYPE=INPUT:SUBMIT FORM=NAME:LoginForm ATTR=NAME:submit
WAIT SECONDS=10

search-first.iim (初回検索マクロ)
VERSION BUILD=8961227 RECORDER=FX
TAG POS=1 TYPE=INPUT:TEXT FORM=ID:SimpleTopForm ATTR=ID:sf_qt CONTENT={{!VAR1}}
TAG POS=1 TYPE=INPUT:IMAGE FORM=ID:SimpleTopForm ATTR=ID:sBtn

search.iim (2回目以降検索マクロ)
VERSION BUILD=8961227 RECORDER=FX
TAG POS=1 TYPE=INPUT:TEXT FORM=ID:myForm ATTR=ID:srchformtxt_qt CONTENT={{!VAR1}}
TAG POS=1 TYPE=INPUT:IMAGE FORM=ID:myForm ATTR=ID:searchBtn

1回目の検索と2回目以降の検索のFormのidが異なるため、別々のマクロに分けてあります。
そして、上記3つのマクロを動作させるJavascriptを用意します。

rakuten-search.js
var userId ="xxxxxxxxxx";  // TODO 設定
var password = "xxxxxxxxx";  // TODO 設定
var keywords = ["検索ワード1",
				"検索ワード2",
				"検索ワード3",
				"検索ワード4",
				"検索ワード5",
				"検索ワード6",
				"検索ワード7",
				"検索ワード8",
				"検索ワード9",
				"検索ワード10",
				"検索ワード11",
				"検索ワード12",
				"検索ワード13",
				"検索ワード14",
				"検索ワード15",
				"検索ワード16",
				"検索ワード17",
				"検索ワード18",
				"検索ワード19",
				"検索ワード20",
				"検索ワード21",
				"検索ワード22",
				"検索ワード23",
				"検索ワード24",
				"検索ワード25",
				"検索ワード26",
				"検索ワード27",
				"検索ワード28",
				"検索ワード29",
				"検索ワード30"
];

// ログイン
iimSet("VAR2",  userId);
iimSet("VAR3",  password);
iimPlay("login");

// 初回検索
iimSet("VAR1", keywords[0]);
iimPlay("search-first");

// 2回目以降検索
for (var i = 1; i < keywords.length; i++) {
	iimSet("VAR1", keywords[i]);
	iimPlay("search");
}
ユーザID、パスワード、検索ワード1~30は各自使用しているものを入力してください。

上記の4つのファイルを
C:\Users\{ユーザID}\Documents\iMacros\Macros
に置きます。
※{ユーザID}は、windowsにログインするときのユーザIDです。
 上記は、Windows Vistaのときの置き場です。
 Windows 8.1だとC:\UsersがC:\ユーザー
 だったりするのでご注意ください。

Firefoxを起動して、rakuten-search.jsを選択、Playボタンをクリックして実行します。

毎日、自動的に動作させる方法は、こちらをご参照ください。
引数の指定は、
imacros://run/?m=rakuten-search.js
を指定してください。
さて、久しぶりにブラウザの自動操作について調べてみる。
2008年当時は、Google Chromeはリリースされたばかり(2008年9月2日)で、
IEは、Windows7も発売前なのでIE8もなくIE7が最新、
Firefoxは、バージョンは3.0(現在は45)という時代だった。
当然ながらIEが主流だったし、ブラウザの自動操作を行うのもIE以外は考えられなかった。
なんで、VBやVCを使ってDLLの中身を解析しながらプログラムしていたのが、懐かしい。

で、今や便利な世の中になったものでブラウザの自動操作をするのにSeleniumという
ツール(フレームワーク)が登場した。
元々は、ブラウザを使ったWebアプリケーションの開発で、
ブラウザ操作のテストを自動化するために、作られたフレームワーク。
人が手でブラウザを操作する代わりにSeleniumがブラウザを操作してくれる。

当時からSeleniumがあれば、数年前に作ってたブラウザ自動操作アプリが
もっと簡単に作れたのに・・・。
嘆いても、しょうがないので、さっそく使ってプログラムを作ってみます。

まずは、こちらからSeleniumをダウンロード。
プログラム言語は、Java, C#, Ruby, Python, Javascriptからお好きなものを選べます。
今回は、Javaでプログラミングしてみます。

そして、インストールと開発環境の設定。今回はJavaということで、Eclipseを使用。
こちらのサイトを参考にしました。

楽天スーパーサーチで自動検索して、山分けポイントをGetするプログラムを作ってみます。
ブラウザはFirefoxを対象にしました。

package rakuten.search;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class UseDriver {

	// ログインURL
	static final String URL = "https://websearch.rakuten.co.jp/login.html";
	// ログインユーザID
	static final String USER_ID = "xxxxxxxxxx"; // TODO 変更
	// ログインパスワード
	static final String PASSWORD = "xxxxxxxxxx";  // TODO 変更

	// ドライバ
	static WebDriver driver = null;

	// 検索するワード
	static String[] keywords = {
			"Google",
			"Firefox",
			"Facebook",
			"Twitter",
			"Line"
	};
	
	public static void main(String[] args) {
		// Firefoxのドライバを生成
		driver = new FirefoxDriver();

		try {
			// ログイン
			driver.get(URL);
			WebElement userId = driver.findElement(By.name("u"));
			userId.sendKeys(USER_ID);
			WebElement passwd = driver.findElement(By.name("p"));
			passwd.sendKeys(PASSWORD);
			passwd.submit();
		} catch (Exception e) {
			return;
		}
		
		// 全ワード検索を行う。
		int i = 0;
		while(i < keywords.length) {
			if (search(i)) {
				i++;
			} 
		}
		driver.quit();
	}
	
	private static boolean search(int i) {
		String key = keywords[i];
		try {
			// ページがロードされ終わるまで待つ。
			// 1秒のタイムアウトを設定。
			Thread.sleep(1000);

			// 検索ワードのテキストボックスを取得。
			WebElement search = driver.findElement(By.name("qt"));
			// 検索する単語を入力。
			search.clear();
			search.sendKeys(key);
			// フォームをサブミット。
			search.submit();
			return true;
		} catch (Exception e) {
			return false;
		}
	}
}

1秒以内に、検索結果が表示されないと次の単語の検索が失敗しますが、
検索結果が表示されるまで、再試行をするようになっています。
このプログラムを動かせば、5口ゲットです。
楽天ツールバーをインストールしていれば、30口まで検索できるはず
なのですが、残念ながら生成したドライバのウィンドウには楽天ツールバーが
表示されないので、5口までとなります。

30口検索するなら、iMacrosというFirefoxのアドオンが便利です。
使い方は、別の機会に。

ブラウザ操作

| コメント(4)

いろいろ試しながらやっているためか、思ってた以上に進捗が悪い。
VBAで先に作って、どのオブジェクト使用しているのかを追ってから
VCに移植した方が早いかもしれない。
まぁ、いいや。じっくりやろう。

何かの役に立てばと思い、購入。
VCの本はないかねぇ。

つまずいたところを備忘録として遺しておきます。
【備忘録】
・前回のプログラムは、VISTA専用。XPで使うにはOSによる切り分けが必要。どっかで考えんといかん。
・ラジオボタンはフォーカス当ててからクリックしないと動かない。(チェックボックスもかな。
コンボボックスは動くのに・・・)
・各コントロールのvalueアトリビュートは0オリジン。(クリック証券のHTMLソース上は1オリジンで書かれている)
・nameアトリビュートを持つForm用のコントロールはnameをキーにした検索可能。書いてないのは、ループして検索しないといけなさそう。
・アンカーは、要素をループして検索するしかなさそう。(nameアトリビュートを持っていない?)

今週中に、売買できるようにしたかったが・・・。まぁ、来週にはできるだろう。
できたら、次はリアルタイム株価の取り込みだ。
まだまだ先は長い。

クリック証券が、Webサービス終了しやがった。
今年1月にWebサービス使うことを目的に口座開いたばっかなのに(怒)。
このAPIがあると、自動発注のプログラムが非常に簡単にできるんだよね。
1日あれば、実装できると見込んでいたのに・・・。5倍は時間かかりそうだ。
APIを使わずに、自動発注するにはブラウザ(IE)を制御するプログラムを
作らなければならない。
しょうがないのでクリック証券ので作り始めたのだが、早速はまりまくっている。
Windows VistaのIEのセキュリティで「保護モード」っていうのがあって、
通常こいつが有効になっている。
こいつが、ブラウザ制御の邪魔をする。ムカッ。
無効にしてやればいいんだけど、それじゃあねぇ・・・。
いろいろ調べていると、こちらに解決方法が。
でも、使用言語が違うので(VBをVCに直してやる必要あり。)、一苦労。
同じようにShell.ApplocationからWindows()メソッドで、
Windowsのインタフェイスを取得するまではいいんだけど、
VCはWindowsインタフェイスを基底クラスのIDispatchPtrで取得するので、
Windowsインタフェイスのポインタ型にダウンキャストしてやらなあかん。
これ、VBでWindowsって書いてあるんで普通にMSDNで探すと
EnvDTE::Windowsのポインタにキャストすればいいと思うよね。
しかし、キャストするとNULLで返ってくる・・・。EnvDTE80::Windows2とかも試してみるがダメ。
よくよく、そのページ読んでると、Windowsの要素(WindowsはWidowのコレクションね)である
WindowがIEオブジェクトとして動いていることに気付く。
ってことは、IEオブジェクト用のコレクションがあるはずと。
そこでもう一度、IE関係のオブジェクトがあるSHDocVwを見てみるとIShellWindowsというのを発見。
ようやく、解決したのでした。
同じように、悩む人出てくるかもしれないので、一応ソース載せときます。
その1のほうです。
その2の方はIEオブジェクトが存在しなくても0で返ってこない。
つまり、IE以外のオブジェクトも返ってきてるので、Itemの最後のインデックスをそのまま使うわけにはいかない。
ItemにIEのWindow追加してやればうまくいくのかな。ってそれなら、その1と変わらんか。
ってわけで、気が向いたらやるけど、こっちも気が向くことはないだろう・・・。

Shell32::IShellDispatchPtr pShell;
HRESULT hr = pShell.CreateInstance(__uuidof(Shell32::Shell));
if(FAILED(hr)){
return false;
}
SHDocVw::IWebBrowser2Ptr pIE;
hr = pIE.CreateInstance(__uuidof(SHDocVw::InternetExplorer));
if(FAILED(hr)){
return false;
}

//IEの表示
pIE->PutVisible(VARIANT_TRUE);
pIE->Navigate(_T("http://www.yahoo.co.jp/"));
pIE->Quit();
::Sleep( 100 );

SHDocVw::IShellWindowsPtr ptr = pShell->Windows();
long lCnt = ptr->GetCount();
pIE = ptr->Item(lCnt-1);
//ページが表示されるまで待つ
while( pIE->Busy == VARIANT_TRUE || pIE->ReadyState != READYSTATE_COMPLETE )
::Sleep( 100 );

プロフィール

よっしー
  
  
フリーでSEをやっています。よろしくお願いします。

2016年4月

          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

最近のコメント