[BlueLeaf1336]> PROBLEMS> iタウンページ解析 iTownDown>

iタウンページ解析 iTownDown > インターネットタウンページ

historyTOP

2005/08/26:作成
2005/08/27:更新

インターネットタウンページTOP

タウンページのインターネット版があります。

たとえば「相生市」の「本屋」を検索するとこんな風になります。

ところでこんなソフトがあります。

NTTのインターネットタウンページで、検索した会社名・電話番号・住所などを、自動的にパソコンに取込み、EXCELや住所録ソフトなどで利用できるCSVファイルに変換するプログラムです。 顧客開拓などの、強力な情報取得ツールとしてご利用できます。
※インターネットタウンページの情報は、「個人情報保護法」に該当しないデータです。

ところで、

★体験版として、50件まで無料でご試用できます。

単に、そこにあるデータを整理するだけでか。

Web上 のデータを効率的に取得する営業ツールを販売してきましたが、諸事情によりの新規の販売を中止させていただくことになりました。

やっぱり。作れそうなので作ってみることにします。

URLを見てみるTOP

まず、Delphi 6 Personal には困ったことに、HttpApp.pas が付属していません。なので、

ちなみに、インターネットタウンページにはこんなこともかいてあります。だからどうというわけではありませんが。

《電話番号リストの無断複写複製を禁じます》

このあたりを参考に、「URLEncode」「URLDecode」できる関数を作成したり主に無断複写複製をしたりします。

//-----------------------------------------------------------------------------
//  2005.08.26  URLエンコード
//  http://www.delphidabbler.com/codesnip.php?action=named&routines=URLEncode&showsrc=1
//  http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/jane/jane/HTTPSub.pas?rev=1.2&content-type=text/vnd.viewcvs-markup
function URLEncode(const S: string): string;
var
    i, l: integer;
    c: char;
begin
    Result := '';
    l := Length(S);
    for i := 1 to l do
    begin
        c := S[i];
        if (c in ['A'..'Z', 'a'..'z', '0'..'9', '-', '_', '.']) then
        begin
            Result := Result + c;
        end
        else
        begin
            Result := Result + '%' + IntToHex(Ord(c), 2);
        end;
    end;
end;

//-----------------------------------------------------------------------------
//  2005.08.26  URLデコード
//  http://www.delphidabbler.com/codesnip.php?action=named&routines=URLDecode&showsrc=1
function URLDecode(const S: string): string;
var
    i, l: integer;
    c: char;
    Hex: string;
    Code: Integer;
begin
    Result := '';
    i := 1;
    l := Length(S);
    while (i <= l) do
    begin
        c := S[i];

        //  % の後ろには2文字続くはず
        if (c = '%') then
        begin
            //  2文字以上残ってないとおかしい
            if (i <= l - 2) then
            begin
                Hex := Copy(S, i + 1, 2);
                Code := StrToIntDef('$' + Hex, -1);
                Inc(i, 2);
            end
            //  やめたる
            else
            begin
                Code := -1;
            end;

            //  デコード失敗
            if (Code < 0) then
            begin
                Result := S;
                Exit;
            end
            //  デコード成功
            else
            begin
                Result := Result + Chr(Code);
            end;
        end
        //  +
        else if (c = '+') then
        begin
            Result := Result + ' ';
        end
        //  その他
        else
        begin
            Result := Result + c;
        end;

        Inc(i);
    end;
end;

この関数(URLDecode)を使って、先の「相生市 本屋」の検索URLを元に戻してみるとこんな感じです。

BEFORE...

http://itp.ne.jp/servlet/jp.ne.itp.sear.SBSSVBasicSearch?Location=%91%8A%90%B6%8E%73&Location_fix=&Category=%96%7B%89%AE&Category_fix=&free_word=&Name=&submitType=&menuType=SelJPref&Gyoumu_cate=6&Media_cate=pda&c_gid=SW0200&n_gid=&r_gid=SW0110&index_dsp=0&index_50on=&c_total=&jsy_pref_name=&jsy_shiku_name=&jsy_cho_name=&jsy_chome_name=&list_cate=&jsy_cate=&jsy_level=&jsy_pref_code=&jsy_shiku_code=&jsy_cho_code=&jsy_chome_code=&jb_code=&Location_select=&r_code=&sta_code=&cate_code=&lm_code=&area_code=&hX=&hY=&rg_area=&rg_shosai=&post_no=&Theme_cate=0&theme_code=&theme_level=&Theme_50on=&matu_level=&cont_id=a00&al_code=&iword=%96%7B%89%AE&gcf=6&svc=2201&clk=&kok=&ktid=&ktel=

AFTER...

http://itp.ne.jp/servlet/jp.ne.itp.sear.SBSSVBasicSearch?Location=相生市&Location_fix=&Category=本屋&Category_fix=&free_word=&Name=&submitType=&menuType=SelJPref&Gyoumu_cate=6&Media_cate=pda&c_gid=SW0200&n_gid=&r_gid=SW0110&index_dsp=0&index_50on=&c_total=&jsy_pref_name=&jsy_shiku_name=&jsy_cho_name=&jsy_chome_name=&list_cate=&jsy_cate=&jsy_level=&jsy_pref_code=&jsy_shiku_code=&jsy_cho_code=&jsy_chome_code=&jb_code=&Location_select=&r_code=&sta_code=&cate_code=&lm_code=&area_code=&hX=&hY=&rg_area=&rg_shosai=&post_no=&Theme_cate=0&theme_code=&theme_level=&Theme_50on=&matu_level=&cont_id=a00&al_code=&iword=本屋&gcf=6&svc=2201&clk=&kok=&ktid=&ktel=

うーん、ひょっとしたら検索語の入力も、こっちでできるかと思ったんですが、「本屋」が2箇所に出てきてます。やっぱり、検索語の入力だけで階層掘って掘っていくだけのことはあります。

とりあえずの目標は、URLは決まったものとして、そのURL内の住所データを「無断複写複製抽出」することにします。あぁ、その前にIEからURLをゲットする所だけ真似してみます。

IEからURLをゲットする(2005/08/27)TOP

次のページにしたがって、SHDocVw_TLB.pasを作成し、uses に加えて、ほとんどそのままのコードを試してみます。

//-----------------------------------------------------------------------------
//  2005.08.27  エクスプローラ(IEも含む)の情報を取り出す
//  http://www.elists.org/pipermail/delphi-talk/1999-October/001582.html
procedure TForm1.Button1Click(Sender: TObject);
var
    IE: ShellWindows;
    OIE: InternetExplorer;
    i: Integer;
begin
    IE := CoShellWindows.Create;
    for i := 0 to IE.Count - 1 do
    begin
        OIE := (IE.Item(i) as InternetExplorer);
        Memo1.Lines.Add('--------------------------');
        Memo1.Lines.Add('Name        : ' + OIE.Name);
        Memo1.Lines.Add('FullName    : ' + OIE.FullName);
        Memo1.Lines.Add('Path        : ' + OIE.Path);
        Memo1.Lines.Add('StatusText  : ' + OIE.StatusText);
        Memo1.Lines.Add('LocationName: ' + OIE.LocationName);
        Memo1.Lines.Add('LocationURL : ' + OIE.LocationURL);
    end;
end;

エクスプローラでフォルダを一つ開いているのと、IEでホームページを一つ開いている状態で実行すると次のような結果になります。

--------------------------
Name        : Microsoft Internet Explorer
FullName    : C:\WINNT\Explorer.EXE
Path        : C:\WINNT\
StatusText  : 10 個のオブジェクト
LocationName: itowndown
LocationURL : file:///C:/Documents%20and%20Settings/Administrator/デスクトップ/itowndown
--------------------------
Name        : Microsoft Internet Explorer
FullName    : C:\Program Files\Internet Explorer\IEXPLORE.EXE
Path        : C:\Program Files\Internet Explorer\
StatusText  :
LocationName: BlueLeaf1336-HOME
LocationURL : http://www.geocities.jp/fjtkt/index.html

見事に取れてます。ただ今回の場合は、単なるエクスプローラの情報は別に欲しくないので、IEであること、それから全然違うURLを開いているのを取得してもその先でエラーを出す(インターネットタウンページの検索結果専用の解析処理だから、たとえばGoogleの検索結果のURLを取得しても手も足も出ない)だけしかできないので、LocationURLが「http://itp.ne.jp/」で始まる場合だけ取得に成功したとするようにします。

こんな感じに。

//-----------------------------------------------------------------------------
//  2005.08.27  指定した文字列で始まるURLをIEが開いている場合にそのURLを戻す
//  http://www.elists.org/pipermail/delphi-talk/1999-October/001582.html
//  uses SHDocVw_TLB << ActiveXの取り込み「Microsoft Internet Controls」
//  uses StrUtils   
function GetUrlFromInternetExplorer(const BeginText: string): string;
var
    IE: ShellWindows;
    OIE: InternetExplorer;
    i: Integer;
    Url, BText: string;

begin
    Result := '';
    BText := BeginText;
    if (BText = '') then BText := 'http:';

    IE := CoShellWindows.Create;
    for i := 0 to IE.Count - 1 do
    begin
        OIE := (IE.Item(i) as InternetExplorer);
        Url := OIE.LocationURL;

        //  先頭を比較する
        if (AnsiStartsText(BText, Url)) then
        begin
            Result := Url;
            Exit;
        end;
    end;
end;

//-----------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
    Memo1.Lines.Add(GetUrlFromInternetExplorer('http://itp.ne.jp/'));
end;

指定したURLのデータをダウンロードするTOP

何回同じことを書く気か、と自分ながらに思ってしまいますが、WinSockを使ったダウンロード処理を少し前に書いたばかりなので、それを流用することにします。ただ、このときはヘッダ情報だけを取ったり調べたりしてたので、最後までダウンロードするようにします。

ここから始めて、ちょっといじってパクリもとのプログラムをちょっと参考にしたのがコレです。

itowndown20050827.zip(245,253bytes)(53,585bytes) 実行ファイルとソースコードです。

まだ、なーんにもしません。ただ、

  1. IEを起動して(失敗しても知ったこっちゃなし)、iタウンページ ライト版を開く。
  2. IE(起動してるつもりで)から、URLを抜き取って表示する。
  3. 抜き取った(もしくは手動で入力した)URLのデータをサーバーからダウンロードして表示する。

だけです。検索結果が何ページあろうが関係なしです。表示しているURLだけを見て、どれだけサーバーがこのページに行ってくれよ、と応答してきたところで黙殺です。ただ、検索結果のページはそんなページ移動を要求したりしませんけど。第一、ステータス200のページ以外はダウンロードしません。

次は、検索結果のページについて調べてみることにします。

EOFTOP