(非公式)TrainConv5 JR東日本 2009年春改変対応

Script JR東日本;
# Copyright(C) 2008 by nTak

路線別時刻表[]:-
<td width="432" class="text-m">${ROSENINFO}</td>
<td width="100" align="center" class="text-m">
${HYPERLINK}
</td>
</tr>
-::

include 'comnlib.inc';
include 'TConv.inc';        // TrainConv用の定義取込み

const
    SiteInfo[5] = (
        'JR東日本',   // サイト名
        0,                  // 変換動作のフラグ
(*!!*)  0x0100,             // Hi:バージョン Lo:リビジョン
        'Copyright(C) 2008 by nTak',
        'http://www.jreast-timetable.jp/'
    );
    C_ForbidMemo= "メモ,データの再配布は禁止です";
    LinkPat[6] = ('/timetable/list','/cgi-bin/st_search.cgi','/www.jreast-timetable.jp/');

(*------------------------------------------------------------------
  自動更新を行う
  戻値:  TRUE: 更新した
          FALSE: 更新失敗または更新ファイルが無い
------------------------------------------------------------------*)
function    TzAutoUpdate:boolean;export;
begin
    Result := DownloadNewScript(DistURL,SiteInfo[2]);   // DistURLは作者のスクリプト配布URL
end;
(*------------------------------------------------------------------
  ノードの定義リストを返す
  戻値:  定義文字列
            リストは次の書式文字列で返す。
            [アイコン番号],[名前],[検索有無フラグ],[URL]
------------------------------------------------------------------*)
function    TzAttachSite(index):string;export;
begin
    case index of
    0: Result := '16,JR東日本時刻表,-1,';
    1: Result := '16,時刻表のみ,0,http://www.jreast-timetable.jp/';
    2: Result := '16,到着時刻付,1,http://www.jreast-timetable.jp/';
    else Result := '';
    end;
end;
(*------------------------------------------------------------------
    URLから読み込んでリンクを登録する
    時刻表ページのURLが指定されていたら変換処理が必要なことを返す
    IN:     index   ノードインデックス
            node    親ノードのID、URLの登録はこのノードに対して実行
            stURL   読込むURL
            cache   キャッシュ有効フラグ
    OUT:    FALSE   路線リンクを登録した
            TRUE    時刻表ページのURLなので変換処理を実行する
------------------------------------------------------------------*)
function    TzGetPageLinks(index,node,stURL,cache):boolean;export;
begin
    Result := False;
    Get(stURL,cache);
    case StrPattern(stURL,LinkPat) of
    3:  begin   // トップから路線リストを作成
        Skipto('</form>');  // 最初のフォームを捨てる
        Skipto('<form action="/cgi-bin/st_search.cgi" method="get">');  // 路線のフォーム
        foreach ln in @formitems['rosen'] do
            begin
            if ln = '' then Next;
                putlog(node,0:@sysdate,1:$$,2:0,3:$?+'?rosen='+ln,4:ICO_TRAIN,5:$:,6:$&+'rosen='+ln);
            end;
        end;
    2:  begin   // 駅名リストを登録
            getlog(node,1:rosen);               // 路線名を取りだして
            foreach lnk in @indexLink[LinkPat[0]] do
                putlog(node,0:@sysdate,1:$$,2:1,3:lnk,4:ICO_EKI2,6:rosen);  // ConvMainで使えるようPOSTSTRに記憶
        end;
    else    // その他は無視
        Result := True;
    end;
end;
//------------------------------------------------------------------
//  時刻表データの抽出と変換
//------------------------------------------------------------------
function    TimePageConv(RosenName,DocData):string;
//var i,j,ns,ds,ss,ln;
    function MakeMark(Kind,lc,rc,AList):string;
    begin
        Result := Kind - ' ' - ' '-'・';
        if Result = ''  then Exit;
        Kind := Result;
        Result := '';
        repeat
            Mark := Kind;
            ll := 0;
            foreach dd in @CSV[AList] do
            begin
                split('−',dd,略,詳細);
                略 := 略 - '#' - lc - rc;       // 種別判定用の文字は削除しておく
                if (TextPos(略,Kind) = 1) and (Length(略) > ll) then    // 最長一致
                begin
                    ll := Length(略);
                    Mark := 略;
                end;
            end;
            kind := Delete(kind,1,Length(Mark));
            Mark := lc + Mark + rc;
            if TextPos(Mark,Result) = 0 then Result := Result + Mark;
        until Kind = '';
    end;
begin
    TableNestMode(3,23);                    // TABLEタグのネスト
    Strip(DocData);
    // 作業変数をクリアする
    init('',Caption,MapURL,DestInfo,KindList,DestList,TimeValue);

   // 駅名と方面名を一緒に処理できるようにしておく
    foreach ln in @Lines[DocData] do
    begin
        ln := Trim(ln); // 前後の空白を除去する
        if (ln = '') or (ln=',') then Next;
        // 1行テキストを分類解析
        if TextPos(RosenName,ln) <> 0 then
        begin
            //  赤羽駅 東北本線 小山・宇都宮方面 (下り),,
            ln  := Replace(ln,' ',' ',TRUE);  // 全角空白を半角空白
            Caption  := '件名,'+(ln - ',');
            DestInfo := CatStr(',','時刻',CSV(ln,1),CSV(ln,0),CSV(ln,2));  // 運転日は後で追加
            MapURL := 'Mapion,'+CSV(ln,0);
            Next;
        end;
        case StrBegIndex(ln,'時,','列車種別','行き先','変更・注意') of
        1:  begin   // 時, 平日 or 土曜・休日
                DestInfo := DestInfo + ','+ CSV(ln,1);
            end;
        2,4:  begin   // 列車種別・列車名 :,無印=普通 快=快速 通快=通勤快速 ラ=ラビット,
                ln := ShiftCSV(ln,1);
                foreach val in @CSV[ln] do                  // 凡例をCSVでスキャンする
                begin
                    if TextPos('=',val) = 0 then Next;
                    split('=',val,略語,車種);
                    KindList := KindList + "#%略語%−%車種%,";  // 凡例を組み立てる
                end;
            end;
        3:  begin   // 行き先・経由 :,無印=宇都宮 金=小金井 磯=黒磯,
                ln := ShiftCSV(ln,1);
                foreach val in @CSV[ln] do                  // 凡例をCSVでスキャンする
                begin
                    if TextPos('=',val) = 0 then Next;
                    split('=',val,略語,行先);
                    DestList := DestList + "{%略語%}−%行先%,";  // 凡例を組み立てる
                end;
            end;
        else if IsDigit(CSV(ln,0)) then // 先頭が数字なら時刻表
            begin
                ln  := Replace(ln,' ','',TRUE);        // 全角空白を消去
                TimeValue := TimeValue + ln + "\n";     // 後で略語を置換する
            end;
        end;
    end;
//  出来上がった時刻テーブルと略語を使って置換する
    TimeTable := '';
    foreach ln in @Lines[TimeValue] do
    begin
        ln := Replace(ln,' ','_',TRUE);  // 空白をマーク
        ln := ExtractCSV(ln,ss);                // まずは時刻を取出し
        ln := ShiftCSV(ln,1);                   //RST 余分なカラムの読み飛ばし
        n := Str2Int(ss);                       // 時刻を取り出す
        TimeTable := TimeTable+((n>=24)?n-24:n)+ ' ';   // 24時以降の補正をして時刻追加
        // 種別・行先と時刻の2つで1ペア
        while CSVCount(ln) > 0 do               // 時刻データがある間
        begin
            ln := ExtractCSV(ln,ns,val);    // 種別_行先 時刻 記号 の順
            Separate(val,9:num,*:ss);       // 注意記号は数字の後につくので
            split('_',ns,種別,行先);        // 行先と種別を分離
            種別 := MakeMark(種別,'<','>',KindList);
            行先 := MakeMark(行先,'{','}',DestList);
            TimeTable := "%TimeTable%  %種別%%行先%%ss%%num% ");
        end;
        TimeTable := TimeTable+"\n";
    end;
    Result := CatStr("\n",Caption,MapURL,C_ForbidMemo,DestInfo,TimeTable)+"凡例,"+KindList+DestList+"\n";
end;
//------------------------------------------------------------------
//  到着時刻データの抽出と変換
//------------------------------------------------------------------
function    TimeReachConv(Station,DocData):string;
begin
    TableNestMode(3,23);                    // TABLEタグのネスト
    Strip(DocData);
    DocData := Replace(DocData,' ',' ',TRUE);  // 全角空白を半角変換
    // 作業変数をクリアする
    init('',Result,Kind,MarkList,Arival);
    pickup := False;
    foreach ln in @Lines[DocData] do
    begin
        ln := Trim(ln) - RegExpr(',\([0-9]+\)',ln); // 前後の空白を除去する
        if ln = '' then Next;
        // 1行テキストを分類解析
        case StrBegIndex(ln,Station,'列車種別,',',,','列車名','運転日,','駅名,','備考,') of
        1:  begin    // 指定駅からの到着時間をリストアップする準備
                ln := ln - ' ';
                atime := RegExpr('([0-9]+:[0-9]+)(発|着)',ln);      // まず着時刻を使う
                発時刻 := dateformat($(0),'hn',2007);
                MarkList := "到着,%Kind%,"+$(0)+',';
                Arival := '';
                pickup := TRUE;
            end;
        2:  begin    // 列車種別
                Kind := (CSV(ln,2)='')? CSV(ln,1) : CSV(ln,2);     // 種別が付いているかも
                Kind := Kind-RegExpr('[0-9]+(号|)',Kind);  // 列車名
                case Kind of
                '各停|各駅停車': Kind := '普通';
                '^普通(?*)': Kind := $(0);  // パターンで( )内に一致した文字列
                end;
            end;
        3..6: Next; // 今のところとりあえず何もしない
        7:  Break;   // Copyright(終り)
        else if Pickup then
            begin
                ln := TrimCSV(ln-' ',3);     // 最初の3項目だけ使う、2列ある情報はあきらめる
                atime := RegExpr('[0-9]+:[0-9]+(着|発)',ln);      // 着時刻を先に抽出
                if atime <> '' then     // 発着時刻が取得できたら
                begin
                    到着 := dateformat(atime,'hn',2007);    // 自動補正されないように年を指定
                    if 到着 < 発時刻 then 到着 := 到着 + @c_dateseconds;    // 24:00を過ぎた
                    到着 :=  (到着 - 発時刻) div 60;
                    eki := CSV(ln,0) - RegExpr('\(*\)',CSV(ln,0));
                    Arival := Arival + eki+":%到着%,";
                end;
            end;
        end;
    end;
    if Arival = '' then Result := ''
    else Result := MarkList + Arival;
end;
(*------------------------------------------------------------------
    時刻表ページのURLから時刻表のテキストを返す
    必要ならリンク先のデータも読み込んで変換する
    IN:     index   ノードインデックス
            pURL    親ノードのURL
            URL     読込むURL
            cache   キャッシュ有効フラグ
    OUT:    TEXT    変換した時刻表テキスト
------------------------------------------------------------------*)
function    TzConvMain(index,pURL,URL,cache,method,PostStr):string; export;
begin
    Result := '';
    Result := '';
    TagStripSet(':DL:DD:BODY:',TX_NONE,TX_NONE); // 無視するタグ
    TagStripSet(':BR:',TX_COMM,TX_NONE);         // <BR>はカンマ変換
    TagStripSet(':DIV:',TX_COMM,TX_NONE);        //RST <DIV>はカンマ変換
    TableNestMode(3,23);                    // TABLEタグのネスト

    Get(URL,cache);                      // 該当駅の路線一覧ページの取得
    StName := Trim(WrapStr($_,'<font color="#FFFFFF">','発車時刻表'));
    foreach n in @clip[路線別時刻表] do
    begin
//      if TextPos('成田エクスプレス',ROSENINFO) = 1 then       // デバッグ用
//      if TextPos(PostStr,ROSENINFO) = 1 then          // リストに無い路線もあるので全部変換
        begin
            foreach ln in @indexlink['',HYPERLINK,URL] do       // 平日と土曜・休日のリンク
            begin
                Get(ln,cache);
                // 不要な路線メニューの部分を切り落とす
                PageClip('<table width="100%" border="0" cellspacing="0" cellpadding="0">',
                        '<table cellspacing="0" cellpadding="1" border="0">');
                BasePage := $_;
                時刻表 := TimePageConv(StName,BasePage);           // 時刻表変換して
                Station := CSV(TextLine(時刻表,0),1)-'駅';  // 件名から駅情報を取る
                Init('',到着時刻);
                if index = 2 then  {                        // 到着時刻付き変換
                    // 平日の列車詳細を取得して各駅の発着時刻から到着時刻を計算する
                    foreach lnk2 in @indexLink['/[0-9]+/train/'] do {
                        Get(lnk2,cache);
                        PageClip('<table width="360" border="0" cellpadding="0" cellspacing="0">',
                                 '<img src="../../../img/spacer.gif" alt="" width="10" height="10"><br>');
                       reachtime := TimeReachConv(Station,$_);
                       if reachtime <> '' then
                          到着時刻 := "%到着時刻%%reachtime%\n";
                     };
                };
                // 到着時刻ができていれば到着時刻付き
                Result := Result + ((到着時刻 <> '') ?"%到着時刻%-----\n":'') + "%時刻表%\n";
             end;
        end;
    end;
end;
//------------------------------------------------------------------
// デバッグ用のメイン
//------------------------------------------------------------------
begin
    TagStripSet(':DL:DD:',TX_NONE,TX_NONE); // 無視するタグ
    TagStripSet(':BR:',TX_COMM,TX_NONE);    // <BR>はカンマ変換
//    'http://www.jreast-timetable.jp/0803/timetable/tt0034/0034040.html'
end.


Posted by RST at 2009年03月26日 16:03│Comments(0)
  コメントは、管理者による確認後ブログに反映されます。(半角400文字まで)