Windows Scripting Host 7

Internet Explorer

今回はInternet Explorerを操作する方法についてみていきます。 Internet Explorerを操作できると色々なオートパイロットができます。 オートパイロットのソフトには色々ありますが、 機能が充実していなかったり、シェアウェアだったりします。 一歩先を行くユーザは自由にカスタマイズできるようにWSHで書きましょう。

細かいところはReference for Visual Basic Developersをご覧ください(1/19/02)。

Internet Explorerを開く

最初に、Internet Explorerオブジェクトを得ます。
    var IE = WScript.CreateObject(
                        "InternetExplorer.Application");
それから、IEを見えるようにしておきます。
    IE.Visible = true;
次のスクリプトは私がいつもデスクトップに置いて使っているものです。
scripts/ie.js
----------------------------------------------------
var IE = WScript.CreateObject(
                    "InternetExplorer.Application");
IE.Visible = true;
IE.Width = 680; IE.Height = 660;
IE.GoHome();
IE4を立ち上げるとたぶん、ウィンドウが横長になってしまうと思います。 私はこれが気に入らないので、開いた後WidthHeightで横と縦の長さを変えています。 これ時点ではページが表示されていないので、最後にホームを表示します。

私の作っているページは最近はたいていこの680という幅を前提にしています。 これより狭いと若干見にくくなるかもしれません。

documentオブジェクト

    IE.Document
とすると、ページ上のJavaScriptでいつも使っている documentオブジェクトを得ることができます。 これさえ得られれば、JavaScriptをふだんから使っている人なら あとは思いのままでしょう。
例えば、下のボタンを押すスクリプトを考えましょう。

これは、

    <FORM NAME=frm1>
    <INPUT TYPE="button" NAME="button1" VALUE="押してね☆"
        ONCLICK='alert("幸せ絶頂!!ですわー!!")';
    </FORM>
となっており、ボタンを押すとメッセージが表示されます。

これをスクリプトで実現するには、 Navigateメソッドで指定したURLに飛びます。

    IE.Navigate(URL);
このNavigateメソッドを働かせると、 指定したURLのページがロードされるまで待ってくれるわけではないようです。 仕方がないので次のように適当にページのロードが終わるまで待ちます。
    while(IE.busy) ;
    while(IE.Document.readyState != "complete") ;
ビジーの間待ち、さらにページのロードが完了するまで待ちます。 気持ちの悪い書き方ですが、これでもそんなにCPUを食うわけではないようです。
実のところこれでちゃんとロードされるまでちゃんと待ってくれるのか分かりません。

このあと、普通にページ上でJavaScriptを使うのと同じようにボタンをクリックします。

scripts/iebutton.js
------------------------------------------------------
var IE = WScript.CreateObject(
                    "InternetExplorer.Application");
IE.Visible = true;
IE.Width = 680; IE.Height = 660;
IE.Navigate(
        "http://member.nifty.ne.jp/aya/wsh/wsh07.htm");
while(IE.busy) ;            //ビジーの間待つ
while(IE.Document.readyState != "complete") ;   //さらに待つ
IE.Document.frm1.button1.click();
このようにすれば、例えば独自の認証方法を取るサイトなど 普通のオートパイロットソフトでは巡回できないページも 自動的にロードすることができます。

追記(10/17)
直前に記述したようなサイトを巡回するとき、 私は20日前から次のようなロードのウェイト方法を取っています。 今のところ一度も失敗していません。 上のような方法ではしょっちゅう失敗していました。
function WaitLoad() {
    var stat, dstart;
    stat = 0;
    while(true)
        if(stat == 0) {
            if(!IE.Busy)
                if(IE.Document.readyState == "complete") {
                    dstart = (new Date()).getTime();
                    stat = 1;
                }
        }
        else {
            if(!IE.Busy &&
                    IE.Document.readyState == "complete") {
                if((new Date()).getTime() >= dstart + 3000)
                    break;
            }
            else
                stat = 0;
        }
}
2つの条件を満たす状態が3秒間続けば、ロード完了とみなしています。

もうちょっと実用的なスクリプトを考えてみましょう。 以下は アサヒコムで供給される毎朝の新聞の総合の記事をクリップするスクリプトです。

scripts/asahicom.js
-----------------------------------------------------------
var d1, id, title, subtitle, contents;
var str, start, end, tmp;
var IE = WScript.CreateObject(
                "InternetExplorer.Application");
IE.Width = 680; IE.Height = 660;
IE.Navigate("http://www.asahi.com/paper/front.html");
while(IE.busy) ;
while(IE.Document.readyState != "complete") ;

str = IE.document.body.innerHTML;

//日付の取得
start = str.indexOf("<I>") + 3;
end = str.indexOf("</I>", 3);
d = new Date(str.substring(start, end));
d1 = d.getYear() + "/" + d.getMonth() + "/" + d.getDate();
str = str.slice(end + 3);

id = 1;
while((start = str.indexOf("<H3>")) != -1) {
    end = str.indexOf("</H3>");
    title = str.substring(start + 5, end);      //タイトル
    tmp = end + 5;
    if((end = title.indexOf("<BR>")) != -1) { //サブタイあり
        start = title.indexOf("-1>", end) + 3;
        subtitle = title.slice(start, -7);
        title = title.substring(0, end);
    }
    else
        subtitle = "";
    end = tmp;
    str = str.slice(end);
    
    //本文
    end = str.indexOf("<HR>");
    contents = str.substring(0, end);
    contents = RemoveTags(contents);    //タグを全て取り除く
    str = str.slice(end + 4);
    
    WScript.Echo("|" + d1 + "|" + (id++) + "|" + title
                + "|" + subtitle + "|" + contents + "^");
}

//以下略
ページがロードされたら、
    str = IE.document.body.innerHTML;
として、全文をstrに格納します。 そして、タグをたよりに日付と各記事のタイトルなどを拾っていきます。
せっかくクリップするので、これを後々にデータベースとして検索などして 活用ができるようにテキストファイルに書きこみます。 次のようなバッチファイルを作って毎日実行すれば、 asahicom.txtという名前のファイルにデータが追加されていきます。
    cscript //nologo asahicom.js >> asahicom.txt
このさい、このテキストファイルの一番最初に
dummy|d:Date YMD|index:Int|title|subtitle|contents^
と書いておきます。 フィールドの区切り文字は"|"、レコードの区切り文字は"^"としています。 こうしておけば、このテキストファイルをソースとする Tabular Data Control をページに貼り込むことができます(その他にも利用方法はあります)。

このスクリプトは、ページの読み込みに失敗したときとか、 休刊日などにまったく対応していないので、 その辺は適当に考えて書き換えてください。

IEのコマンドを実行する

ExecWBメソッドを使うとIEのコマンドを実行することができます (これって古いリファレンスに無いんだけど)。
    IE.ExecWB(cmdID, cmdexecopt [,pvaIn] [,pvaOut]) 
cmdIDはコマンドを指定します。 具体的には
ここを見てください。
cmdexecopt
    OLECMDEXECOPT_DODEFAULT
    OLECMDEXECOPT_DONTPROMPTUSER
    OLECMDEXECOPT_PROMPTUSER
    OLECMDEXECOPT_SHOWHELP
から選びます。pvaInは何か入力する変数、pvaOutは出力する変数です。
scripts/saveas.wsf
----------------------------------------------------
<JOB ID="ref">
 <REFERENCE GUID="{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}"/>
 <SCRIPT LANGUAGE="JavaScript">
  var IE = WScript.CreateObject("InternetExplorer.Application");
  IE.Visible = true;
  IE.GoHome();
  WScript.Sleep(10000);     //10秒待つ(すごく手抜き)
  IE.ExecWB(OLECMDID_SAVEAS, OLECMDEXECOPT_DODEFAULT);
  WScript.Echo(sss);
 </SCRIPT>
</JOB>
上のスクリプトはホームを表示して名前を付けて保存のコマンドを発行します。 ただダイアログを出すだけです。
cmdIDを変えると色々なことができるので試してみましょう。

first, prev, next, noframe, exit
Written 7/19/98