[BlueLeaf1336]> PROBLEMS> MizuhoGetter>

MizuhoGetter > HTMLソースの取得と解析

historyTOP

2004/10/30:作成

overviewTOP

実は、以前に作成した リンクタグ作成ユーティリティ HrefBuilderというプログラムで、HTMLのダウンロードと非常に簡単な解析(タイトルを取得するだけ)をやったことがあります。今回はそれを流用することにします。

さて、みずほ銀行のウェブサイトは今のところSJISで記述されているようなので、ややこしいことは言わずに普通に取得して大丈夫のようです。

HTMLの取得TOP

やることは2つ。現在インターネットがつかえる状況にあるかのチェック。実際の取得。方法は、答えが書いてあるページを探し出すだけで、以前の参考にしたページがそのまま健在でした。

上はCで書かれており、下はDelphiで書かれています。もちろんここではDelphiを使いますので、上は翻訳が入りますが、下はそのままで使えます。もっともまったく同じのを再掲しても仕方がないので、読み取りバッファの使い方を少し変えたものにします。確かこの方法は、こける Wired - Winsockを使ってみようぜ で使用されてて、へー、と思った方法です。

HTMLの取得 - ソースコードTOP

uses
    Windows, SysUtils, Classes, WinInet;

//  ---------------------------------------------------------------------------
//  つながってますか?
function IsOnline(): Boolean;
begin
    Result := InternetAttemptConnect(0) = ERROR_SUCCESS;
end;

//  ---------------------------------------------------------------------------
//  HTMLソースの取得
function GetHtmlFile(Stream: TStream; const URL: string): Boolean;
const
    UserAgent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)';
var
    hSess: HINTERNET;
    hServ: HINTERNET;
    Buf: string;
    Len: Cardinal;
begin
    Result:=False;

    //  インターネットにつながってるかチェック
    if not IsOnline() then exit;

    //  セッションを開いて
    hSess := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
    try
        //  いけてたら
        if Assigned(hSess) then
        begin
            //  URLを開く
            hServ := InternetOpenUrl(hSess, PChar(url), nil, 0, INTERNET_FLAG_RELOAD, 0);
            try
                //  いけてたら
                if Assigned(hServ) then
                begin
                    //  全部読み込めるまでくり返す
                    while true do
                    begin
                        //  読み取りバッファのサイズを 1024 バイトにセット
                        SetLength(Buf, 1024);
                        //  読み取り
                        InternetReadFile(hServ, @Buf[1], Length(Buf), Len);
                        //  読み込んだサイズを調べる(0なら最後までいけた)
                        if Len = 0 then Break;
                        //  読み込んだサイズにバッファを調節
                        SetLength(Buf, Len);
                        //  引数のストリームに書き込む
                        Stream.Write(Buf[1], Length(Buf));
                    end;
                    //  ストリームの現在位置を最初に戻す
                    Stream.Position := 0;
                    Result := True;
                end;
            finally
                //  URLを閉じる
                InternetCloseHandle(hServ);
            end;
        end;
    finally
        //  セッションを閉じる
        InternetCloseHandle(hSess);
    end;
end;

この関数を使用すると、たとえば、指定したURLのソースをTMemoに表示するなら、こんな感じになります。

procedure TForm1.Button1Click(Sender: TObject);
var
    MS: TMemoryStream;
begin
    MS := TMemoryStream.Create;
    GetHtmlFile(MS, Edit1.Text);
    Memo1.Lines.LoadFromStream(MS);
    MS.Free;
end;

解析TOP

次は解析です。こっちが邪魔くさいんですが、HTMLそのものを理解するようなプログラムを作りたいわけではないので、この文字があったらどう、とかこの次の行がコレのはず、見たいな嫌過ぎる前提を持ち込むことにします。あ、解析といっても当選番号が実際に記述されているページへのリンク集のページの解析ですので、ここでいきなり番号が取得されるわけではないです。もっと簡単です。

「リンク」だとわかっているわけなので、「href」とそれに続く「XXXX.html」を見つけだすだけです。

整理すると、

という手順になると思います。実際にしんどいのは、この先ですね。どう考えても。そういうわけで、まずは、上記の順番で処理するプログラムを作ればよいということになります。

ちょっと考えるとそれよりも直リンクした方がよいですね。つまり、

に対して、連番部分をプログラムで次々と生成して「Not Found」が帰ってきたら終了、のようにしたほうがよほど賢そうです。適当なURLで試してみると、このサイトのサーバーは

<TITLE>404 Not Found</TITLE>

を返すようなので、この文字列が含まれていたら終了、でよさそうです。

長くなったので次へ。

EOFTOP