【HSP】2017年版 F1ランキングページを生成してみる【その10】

renault

開幕までになんとかしたいと思っているので、短期集中な感じになってしまいましたね。今回で10回目になります。さて、その今回は生成されるファイルをフォルダを用意しておいて、そこに入れるようにプログラムを改良していきたいと思います。主に生成されるファイルは

  • レース単位のURLを格納してあるCSVファイル
  • レース毎の簡易htmlファイル
  • レース毎のCSVファイル
  • 全レース結果CSVファイル

といったところです。ひとまずURLの格納してあるCSVは実行ファイルと同じ場所にある方がいいと思うのでそのままにします。他のファイルはそれぞれ「html」「csv」のフォルダを用意して、そこに保存するようにしていきたいと思います。しかも、プログラムでフォルダを有無を判断してなければ作成する、みたいな感じにしていきましょう。

スポンサーリンク

フォルダの有無を確認、無ければ作成

フォルダの有無を確認するには「dirlist」を使用します。取得モードを設定することでフォルダ(ディレクトリ)のみを取得することもできちゃいます。

ディレクトリ一覧を取得

dirlist p1,”filemask”,p2

p1=変数 : ディレクトリ一覧を格納する文字列型変数
“filemask” : 一覧のためのファイルマスク
p2=0~(0) : ディレクトリ取得モード

取得モードは「5」にすることでフォルダのみを取り出せるようになります。ファイルマスクはワイルドカード「.」でOKなので、

dirlist chk, "*.*", 5
if instr(chk, 0, "html") = -1 : mkdir "html"
if instr(chk, 0, "csv") = -1 : mkdir "csv"

という記述をプログラムの先頭に入れておけばフォルダチェック&生成は完了。実行してみると

ちゃんとフォルダが作成されてますね!

それぞれのフォルダにファイルを生成するようにする

htmlはhtmlフォルダに、csvはcsvフォルダに格納するようにプログラムを改良していきたいと思います。

フォルダの場所を保存しておく

文字で書くとちょっぴり意味不明な感じですが、要するに

  • 実行ファイルのあるアドレス(パス)を取得しておく

というのがポイントになります。これを中心にしてhtmlフォルダなら「\html」を追加してあげればいいですし、CSVも同様に「\CSV」を追加する形になります。ちなみにhspでは、実行ファイルのある場所(カレントディレクトリ)は

dir_cur

という変数に格納されています。なので、これを用いてhtmlとCSVの保存先のパスを作成しておきます。また、home_posという名前でカレントディレクトリも格納しておきましょう。

home_pos = dir_cur
html_pos = dir_cur + "\\html"
csv_pos  = dir_cur + "\\csv"

※hspでは\がエスケープ文字になっているので、2つ続けて書く必要があります。

CSVが存在するかチェックする部分の改修

// csv_check
dirlist chk, "Raceresulturl.csv"
await 1
if (stat = 0) {
    csv_text = "GP Name,URL\n"
} else {
    notesel csv_text
    noteload "Raceresulturl.csv"
    noteunsel
}
dirlist chk, "allresult.csv"
await 1
if (stat = 0) {
    allresult_csv = "driver Name"
} else {
    notesel allresult_csv
    noteload "allresult.csv"
    noteunsel
}

この部分、上はURLの抽出なのでそのままでOKなのですが、保存場所を切り替える作業をする上で、現在どのディレクトリで作業をしているかを明確にしておく方が安全だと思われます。なので、URLのCSVの有無をチェックする前に作業場所のフォルダに移動しておきましょう。フォルダ(ディレクトリ)の移動は「chdir」を使います。

// csv_check
chdir home_dir
dirlist chk, "Raceresulturl.csv"
await 1
if (stat = 0) {
    (略)

で、全戦結果のCSVはCSVフォルダに格納するので、有無の確認もCSVフォルダに移動しておく必要があります。

    (略)
}
chdir csv_dir
dirlist chk, "allresult.csv"
await 1
if (stat = 0) {
    allresult_csv = "driver Name"
} else {
    (略)

これでOK。

ダウンロードの前にもフォルダ場所の指定

フォルダの現在地を把握しておけばいいのですが、プログラムを改良していくと複雑になっていくのは必至なので、常に指定する形にしてリスクヘッジしておきます。まずはダウンロードする前に場所指定。

//レースリザルト一覧ページダウンロード
chdir home_pos
download_url = "https://www.formula1.com/en/results.html/2016/races.html"
gosub *dl_start

レースリザルト一覧のダウンロード(URL抽出前)と

repeat 40, 1
    if gpname(cnt) = "" : break //レース名が空なら終了
    //レース結果のCSVファイルが存在してるかチェック
    dirlist chk, gpname(cnt)+".csv"
    if (stat ! 0) : continue
    //存在していない場合、ダウンロードする
    chdir home_pos
    download_url = geturl(cnt)
    gosub *dl_start
    //データ化処理をする
    gpname_now = gpname(cnt)
    gosub *race_csv
loop

URLからレース毎のページダウンロード前に「chdir home_pos」を設置。

csvを読み込むときにも設置

せっかく作ったcsvファイルを読み込む時に作業しているフォルダが違っていたらエラーになってしまいます。なので、その前にも設置。

// url→raceresultダウンロード
chdir home_pos
notesel csv_text
noteload "Raceresulturl.csv"
repeat notemax
    noteget text_line, cnt
    split text_line, ",", gpname(cnt), geturl(cnt)
loop
noteunsel
await 1

ファイルの存在チェック前にも必要です

ここまで来ると面倒くさいぐらいなのですが、リスクヘッジなので。もちろんファイルチェックの前にも設置しておきましょう。

repeat 40, 1
    if gpname(cnt) = "" : break //レース名が空なら終了
    //レース結果のCSVファイルが存在してるかチェック
    chdir csv_pos
    dirlist chk, gpname(cnt)+".csv"
    if (stat ! 0) : continue
    //存在していない場合、ダウンロードする
    chdir home_pos
    download_url = geturl(cnt)
    gosub *dl_start
    //データ化処理をする
    gpname_now = gpname(cnt)
    gosub *race_csv
loop

ファイル出力時にも設置

で。ようやく今回のポイントとなる部分。ファイル出力する時に対応するフォルダに生成したいので、当然ここにも「chdir」を設置します。まずはURL一覧の出力先は「home_pos」

// csv出力
chdir home_pos
if (gpname(0) ! "") {
    notesel csv_text
    notesave "Raceresulturl.csv"
    noteunsel
    await 1
    dialog "save new csv file"
}

htmlは「html_pos」

//HTML出力
chdir html_pos
notesel html_text
notesave gpname_now + ".html"
noteunsel
await 1

csvは「csv_pos」に

// csv出力
chdir csv_pos
notesel csv_text
notesave gpname_now + ".csv"
noteunsel
await 1
// allresult出力
chdir csv_pos
notesel allresult_csv
notesave "allresult.csv"
noteunsel
await 1

それぞれ抜粋しているので、わかりにくい場合は全コードは最後に載っているのでそちらで確認してみてください(chdirで検索するといいかも)。

すべて整ったら実行!

さっそく実行してみます!

しばらくするとウィンドウが消えれば実行完了! フォルダをみてみると

無事フォルダわけできてました。もう一度起動してみると、上書きも起こることなく終了…完璧です!!

まとめ

今回はファイルの保存先を分けるように改良しました。これでどこにどのファイルが存在するのかがわかりやすくなったんじゃないでしょうか? 最後に全コードを載せておきますので、実行してみてくださいね!

//HSPモジュール SAKMISさんのを使用しています
//命令→lfcc ファイルネーム
//読み込み→改行置換→保存
    #module
    #deffunc lfcc str filename
;   mref filename,32
;   mref status,64
        exist filename
        size=strsize
        if size=-1 : status=-1 : return
        sdim ss,size+1,1
        bload filename,ss,size

        ii=0
        code=0
        sdim data,size<<1,1

    repeat size
        tt = peek (ss,cnt)
        if tt=10 : code=10 : break
        if tt=13 {
        code=13
        tt = peek (ss,cnt+1)
        if tt=10 : code=0
        break
        }
    loop

        if code=0 : status=-1 : return

    repeat size
        tt = peek (ss,cnt)
        if tt=code : wpoke data,ii,2573 : ii+2 : continue
        poke data,ii,tt : ii++
    loop

        bsave filename,data,ii
        status=ii
    return
#global

    #include "hspinet.as"
    //#include "hspext.as"

    // into_pos
    home_pos = dir_cur
    html_pos = dir_cur + "\\html"
    csv_pos  = dir_cur + "\\csv"

    // folder_check
    dirlist chk, "*.*", 5
    if instr(chk, 0, "html") = -1 : mkdir "html"
    if instr(chk, 0, "csv") = -1 : mkdir "csv"

    // csv_check
    chdir home_pos
    dirlist chk, "Raceresulturl.csv"
    await 1
    if (stat = 0) {
        csv_text = "GP Name,URL\n"
    } else {
        notesel csv_text
        noteload "Raceresulturl.csv"
        noteunsel
    }
    chdir csv_pos
    dirlist chk, "allresult.csv"
    await 1
    if (stat = 0) {
        allresult_csv = "driver Name"
    } else {
        notesel allresult_csv
        noteload "allresult.csv"
        noteunsel
    }


    // ネット接続の確認
    netinit
    if stat : dialog "ネット接続できません" : end

    // 初期設定
//  download_url = "https://www.formula1.com/en/results.html/2017/drivers.html"
//  download_url = "https://www.formula1.com/en/results.html/2016/races/938/australia/race-result.html"
    sdim firstname,  40, 40
    sdim familyname, 40, 40
    sdim country,    40, 40
    sdim teamname,   40, 40
    sdim getpoint,   40, 40
    // 追加したもの
    sdim position,   40, 40
    sdim carnumber,  40, 40
    sdim laps,       40, 40
    sdim times,      40, 40
    sdim geturl,     200, 40
    sdim gpname,     200, 40

    //レースリザルト一覧ページダウンロード
    chdir home_pos
    download_url = "https://www.formula1.com/en/results.html/2016/races.html"
    gosub *dl_start


    /*url抽出部分*/
    *skippoint //チェック用ラベル
    notesel htmlfile
    noteload url_pagename
    url_cnt = 0
    repeat notemax
        noteget text_line, cnt
        // RACE_URL
        if (instr(text_line, 0, "dark bold ArchiveLink") ! -1) {
            split text_line, "\"", buf
            // csv_text check
            if (instr(csv_text, 0, buf(1)) ! -1) : continue
            // geturl
            geturl(url_cnt) = buf(1)
            noteget gpname(url_cnt), cnt+1
            strrep gpname(url_cnt), " ", ""
            gpname(url_cnt) += " GP result"
            url_cnt++
        }
    loop
    //test
    //dialog geturl(0)
    //dialog gpname(0)
    noteunsel

    //make_csv
    //csv_text = "GP Name,URL\n"
    repeat 40
        if gpname(cnt) = "" : break
        csv_text += gpname(cnt) + ",https://www.formula1.com" + geturl(cnt) + "\n"
    loop

    // csv出力
    chdir home_pos
    if (gpname(0) ! "") {
        notesel csv_text
        notesave "Raceresulturl.csv"
        noteunsel
        await 1
        mes "save new urlcsv file"
    }


    // url→raceresultダウンロード
    chdir home_pos
    notesel csv_text
    noteload "Raceresulturl.csv"
    repeat notemax
        noteget text_line, cnt
        split text_line, ",", gpname(cnt), geturl(cnt)
    loop
    noteunsel
    await 1

    repeat 40, 1
        if gpname(cnt) = "" : break //レース名が空なら終了
        //レース結果のCSVファイルが存在してるかチェック
        chdir csv_pos
        dirlist chk, gpname(cnt)+".csv"
        if (stat ! 0) : continue
        //存在していない場合、ダウンロードする
        chdir home_pos
        download_url = geturl(cnt)
        gosub *dl_start
        //データ化処理をする
        gpname_now = gpname(cnt)
        gosub *race_csv
    loop

    end
    stop



    /* ダウンロードサブルーチン化 */
    *dl_start
    // URL分解
    if (instr(download_url, 0, ".html") ! -1) or (instr(download_url, 0, ".php") ! -1) { //.html .phpが含まれているなら
        split download_url, "/", result
        url_pagename = result(stat-1)
        url_address  = download_url
        strrep url_address, url_pagename, ""
    } else { // 含まれていない場合はindex.htmlにする
        url_address  = download_url
        url_pagename = "index.html"
    }

    neturl url_address
    netrequest url_pagename

    *main
    //取得待ち確認
    netexec res
    if res > 0 : goto *comp
    if res < 0 : goto *bad
    await 50
    goto *main

    *bad
    //エラー
    neterror estr
    dialog "ERROR "+estr
    end
    stop

    *comp
    mes "DOWNLOAD 完了"
    lfcc url_pagename

    return


    /* レース結果処理サブルーチン化 */
    *race_csv
    notesel htmlfile
    noteload url_pagename
    first_cnt = 0 : family_cnt = 0 : country_cnt = 0 : teamname_cnt = 0
    position_cnt = 0 : carnumber_cnt = 0 : laps_cnt = 0 : times_cnt = 0
    repeat notemax
        noteget text_line, cnt
        // 着順
        if (instr(text_line, 0, "<td class=\"dark\">") ! -1) {
            strrep text_line, "<td class=\"dark\">", ""
            strrep text_line, "</td>", ""
            strrep text_line, " ", ""
            position(position_cnt) = text_line
            position_cnt++
            continue
        }
        // カーナンバー
        if (instr(text_line, 0, "<td class=\"dark hide-for-mobile\">") ! -1) {
            strrep text_line, "<td class=\"dark hide-for-mobile\">", ""
            strrep text_line, "</td>", ""
            strrep text_line, " ", ""
            carnumber(carnumber_cnt) = text_line
            carnumber_cnt++
            continue
        }
        // ファーストネーム
        if (instr(text_line, 0, "<span class=\"hide-for-tablet\">") ! -1) {
            strrep text_line, "<span class=\"hide-for-tablet\">", ""
            strrep text_line, "</span>", ""
            strrep text_line, " ", ""
            firstname(first_cnt) = text_line
            first_cnt++
            continue
        }
        // ファミリーネーム
        if (instr(text_line, 0, "<span class=\"hide-for-mobile\">") ! -1) {
            strrep text_line, "<span class=\"hide-for-mobile\">", ""
            strrep text_line, "</span>", ""
            strrep text_line, " ", ""
            familyname(family_cnt) = text_line
            family_cnt++
            continue
        }
        // 所属チーム
        if (instr(text_line, 0, "semi-bold uppercase hide-for-tablet") ! -1) {
            split text_line, ">", buf
            split buf(1), "<", result
            teamname(teamname_cnt) = result(0)
            teamname_cnt++
            continue
        }
        // ラップ
        if (instr(text_line, 0, "<td class=\"bold hide-for-mobile\">") ! -1) {
            strrep text_line, "<td class=\"bold hide-for-mobile\">", ""
            strrep text_line, "</td>", ""
            strrep text_line, " ", ""
            laps(laps_cnt) = text_line
            laps_cnt++
            continue
        }
        // タイム
        if (instr(text_line, 0, "<td class=\"dark bold\">") ! -1) and (instr(text_line, 0, "</td>") ! -1) {
            split text_line, ">", buf
            split buf(1), "<", result
            times(times_cnt) = result(0)
            times_cnt++
            continue
        }
        // 獲得ポイント
        if (instr(text_line, 0, "<td class=\"bold\">") ! -1) {
            strrep text_line, "<td class=\"bold\">", ""
            strrep text_line, "</td>", ""
            strrep text_line, " ", ""
            getpoint(point_cnt) = text_line
            point_cnt++
            continue
        }

    loop
    noteunsel

    //make_area
    html_text = "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<meta http-equiv=\"content-language\" content=\"ja\">\n<title>2017レースリザルト</title>\n<style>\nbody {\ncounter-reset: drivername;\n}\nli {\ndisplay: flex;\n}\ndiv {\nmargin-right: 1rem;\n}\n.drivername, .team {\nwidth: 12rem;\n}\n.country {\nwidth: 6rem;\n}\n.drivername:before {\ncounter-increment:drivername;\ncontent:counter(drivername) \"位 \";\ndisplay: inline-flex;\nwidth: 3rem;\n}\n</style>\n</head>\n<body>\n<h1>2017レースリザルト</h1>\n<ul>"
    csv_text = "position,firstname,familyname,carnumber,teamname,point,laps,times\n"
    /* 項目部分取り出し・追加 */
    notesel allresult_csv
    noteget text_line, 0
    split text_line, ",", buf
    comma = stat
    text_line += "," + gpname_now + ":pos,pts,laps"
    noteadd text_line, 0, 1

    repeat 40
        if firstname(cnt) = "" : break
        html_text += "<li>\n<div class=\"position\">[" + position(cnt) + "]</div>\n<div class=\"drivername\">" + firstname(cnt) + " " + familyname(cnt) + "</div>\n<div class=\"country\">" + carnumber(cnt) + "</div>\n<div class=\"team\">" + teamname(cnt) + "</div>\n<div class=\"point\">" + getpoint(cnt) + "pt</div>\n<div class=\"times\">" + laps(cnt) + "(" + times(cnt) + ")</div>\n</li>\n"
        csv_text += position(cnt) + "," + firstname(cnt) + "," + familyname(cnt) + "," + carnumber(cnt) + "," + teamname(cnt) + "," + getpoint(cnt) + "," + laps(cnt) + "," + times(cnt) + "\n"

        /* データの格納しなおし */
        drivername = firstname(cnt) + " " + familyname(cnt) : title gpname_now + ":" + drivername
        data_box = position(cnt) + "," + getpoint(cnt) + "," + laps(cnt) +"(" + times(cnt) + ")"
        /* ドライバーデータの追加 */
        if (instr(allresult_csv, 0, drivername) = -1) {
            addcomma = "" : repeat comma: addcomma += "," : loop
            allresult_csv += drivername + addcomma + data_box + "\n"
        } else {
            repeat notemax
                noteget text_line, cnt
                if (instr(text_line, 0, drivername) ! -1) {
                    split text_line, ",", buf
                    dirver_comma = comma - stat + 1
                    addcomma = "" : repeat dirver_comma : addcomma += "," : loop
                    text_line += addcomma + data_box
                    noteadd text_line, cnt, 1
                }
            loop
        }
    loop
    noteunsel
    html_text += "</ul>\n</body>\n</html>\n"


    nkfcnv html_text,html_text,"Sw"

    //HTML出力
    chdir html_pos
    notesel html_text
    notesave gpname_now + ".html"
    noteunsel
    await 1
    // csv出力
    chdir csv_pos
    notesel csv_text
    notesave gpname_now + ".csv"
    noteunsel
    await 1
    // allresult出力
    chdir csv_pos
    notesel allresult_csv
    notesave "allresult.csv"
    noteunsel
    await 1



    mes "save html file"

    return

stop
スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする