HSPでF1ポイントのランキングページを生成してみる~その4~【HSP活用術】

html images

前回はデータを取り出しが完了しました。今回はページの作成部分に取り掛かりたいと思います。

HSPでF1ポイントのランキングページを生成してみる~その3~【HSP活用術】
前回はドライバー名が格納できたので、今回はそれを以外のデータを取り出していきたいと思います。 以前、(アドレス)は以下...

以前、[F1公式サイトのスクレイピング](アドレス)は以下から。

formula1公式サイトのドライバーズランキングをスクレイピングしてみよう その4
おなじみになりつつありますが、まずはそれぞれのクラス名やタグの整理、コードを再確認しておきましょう。 クラス名、タグ 【...
formula1公式サイトのドライバーズランキングをスクレイピングしてみよう その3
それぞれのクラス名やタグの整理、コードを再確認しておきましょう。 まずはクラス名、タグ 【ドライバー名】 ファ...
formula1公式サイトのドライバーズランキングをスクレイピングしてみよう その2
前回(その1)で、それぞれのクラス名やタグの整理をしました。あらためて、確認してみましょう。 【ドライバー名】 ...
formula1公式サイトのドライバーズランキングをスクレイピングしてみよう その1
ニッチ過ぎて需要があるかどうかわかりませんが。。。javascriptで組んで、最終的にはブックマークレットにしてお手軽に実行できる...
スポンサーリンク

取り出したデータと格納先

ここまでで取り出せたデータとその格納先です

  • 【ドライバー名】
    • ファーストネーム→firstname(数字)
    • ファミリーネーム→familyname(数字)
  • 【国籍】
    • country(数字)
  • 【所属チーム】
    • teamname(数字)
  • 【獲得ポイント】
    • getpoint(数字)

という感じ。数字の部分はそれぞれの格納先共通で、たとえばルイス・ハミルトンならこの時点でランキングトップなので0、ニコ・ロズベルグなら1という風になってます。

ページの雛形を用意する

実際にポイントライキングのページを作成していきたいと思います。まず、雛形になるhtmlを考えていきましょう。大枠は以下のような感じでしょうか。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="content-language" content="ja">
    <title></title>
</head>
<body>

</body>
</html>

この雛形に必要なものを書き込んでhtmlファイルとして保存してあげるのが最終目標になります。とはいえ、いきなり追加要素をプログラミングするわけにもいかないので、まずは実際に完成目標のhtmlファイルを作ってみることにしましょう。

htmlを作成する

html images

イメージは上のようなシンプルなもので考えてます。あとからスタイルシートなどで装飾すればいいですしね。これをhtmlで書いてみると

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="content-language" content="ja">
    <title>2016ドライバーランキング</title>
    <style>
        body {
            counter-reset: drivername;
        }
        li {
            display: flex;
        }
        div {
            margin-right: 1rem;
        }
        .drivername, .team {
            width: 9rem;
        }
        .country {
            width: 6rem;
        }
        .drivername:before {
            counter-increment:drivername;
            content:counter(drivername) "位 ";
        }
    </style>
</head>
<body>
    <h1>2016ドライバーランキング</h1>
    <ul>
        <li>
                <div class="drivername">Louis Hamilton</div>
                <div class="country">GBR</div>
                <div class="team">Mercedes</div>
                <div class="point">250</div>
        </li>
        <li>
                <div class="drivername">Louis Hamilton</div>
                <div class="country">GBR</div>
                <div class="team">Mercedes</div>
                <div class="point">250</div>
        </li>
        <li>
                <div class="drivername">Louis Hamilton</div>
                <div class="country">GBR</div>
                <div class="team">Mercedes</div>
                <div class="point">250</div>
        </li>
        <li>
                <div class="drivername">Louis Hamilton</div>
                <div class="country">GBR</div>
                <div class="team">Mercedes</div>
                <div class="point">250</div>
        </li>
        <li>
                <div class="drivername">Louis Hamilton</div>
                <div class="country">GBR</div>
                <div class="team">Mercedes</div>
                <div class="point">250</div>
        </li>
    </ul>
</body>
</html>

こういう感じになりました。ちなみに、順位の部分はCSSにて対応してるのでhtml上には該当部分がない状態です(その方がシンプルに処理できそうなので)。また、ダミーなので5位までですが、これがドライバー人数分になるイメージですね。みてもらえばわかるのですが、繰り返し出てくる

<li>
        <div class="drivername">Louis Hamilton</div>
        <div class="country">GBR</div>
        <div class="team">Mercedes</div>
        <div class="point">250</div>
</li>

この部分をHSPで作ることになります。ドライバー名、国籍、チーム名、ポイントなので取り出したデータをそのまま使う形で大丈夫そうですね。

HSPでhtmlを成形していく

htmlをプログラミングで生成するというとなんだか難しそうな感じですが、実はテキスト(文章)を作っていくのと同じだったりします。なので上の例をそのまま書くと

html_text = "<li>\n
                <div class=\"drivername\">Louis Hamilton</div>\n
                <div class=\"country\">GBR</div>\n
                <div class=\"team\">Mercedes</div>\n
                <div class=\"point\">250</div>\n
            </li>"

となります(みやすくするために改行してます)。そして、この内容をファイル保存する際にhtmlの拡張子にしてあげればOK。これならそんなに難しくないですよね。ちなみに改行は「¥n」、ダブルクォーテーションを出力するためには「¥”」としてあげる必要があるので注意してください(表示上全角で書いてますが、スクリプト上では半角です)。

ところで前回までで内容確認のために表示させていた部分があったかと思います。

//debug
chk = ""
repeat 40
    if firstname(cnt) = "" : break
    chk += firstname(cnt) + " " + familyname(cnt) + "\t(" + country(cnt) + ") \t【" + teamname(cnt) + "】 " + getpoint(cnt) + "p\n"
loop
mesbox chk, 640, 400

stop

ここで全ドライバー文の確認を賄っていたとなれば…これを改造すればhtml用のテキストが成型できそうですよね。なので、これを改造していきたいと思います。ここでもう一度格納変数を確認。

  • 【ドライバー名】
    • ファーストネーム→firstname(数字)
    • ファミリーネーム→familyname(数字)
  • 【国籍】
    • country(数字)
  • 【所属チーム】
    • teamname(数字)
  • 【獲得ポイント】
    • getpoint(数字)

今回、ドライバー名は分けずに処理、他はそれぞれdivで括っているのでイメージとしては

<li>
        <div class="drivername">firstname(cnt) familyname(cnt)</div>
        <div class="country">country(cnt)</div>
        <div class="team">teamname(cnt)</div>
        <div class="point">getpoint(cnt)</div>
</li>

という感じですかね。ちゃんとHSPで処理できるように整えてみると

html_text = "<li>\n
                <div class=\"drivername\">" + firstname(cnt) + " " + familyname(cnt) + "</div>\n
                <div class=\"country\">country(cnt)</div>\n
                <div class=\"team\">teamname(cnt)</div>\n
                <div class=\"point\">getpoint(cnt)</div>\n
            </li>\n"

こんな感じですね。実際には改行をしないで一文にしてしまうので

html_text = "<li>\n<div class=\"drivername\">" + firstname(cnt) + " " + familyname(cnt) + "</div>\n<div class=\"country\">" + country(cnt) + "</div>\n<div class=\"team\">" + teamname(cnt) + "</div>\n<div class=\"point\">" + getpoint(cnt) + "</div>\n</li>\n"

となります。さらにhtmlとしてファイルを保存するために

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="content-language" content="ja">
    <title>2016ドライバーランキング</title>
    (中略)
</head>
<body>
    <h1>2016ドライバーランキング</h1>
    <ul>

という前半部分と

    </ul>
</body>
</html>

の締めの部分を追加しておきたいところです。これらを考慮してスクリプトを書いてみると…

//debug
html_text = "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<meta http-equiv=\"content-language\" content=\"ja\">\n<title>2016ドライバーランキング</title>\n<style>\nbody {\ncounter-reset: drivername;\n}\nli {\ndisplay: flex;\n}\ndiv {\nmargin-right: 1rem;\n}\n.drivername, .team {\nwidth: 9rem;\n}\n.country {\nwidth: 6rem;\n}\n.drivername:before {\ncounter-increment:drivername;\ncontent:counter(drivername) \"位 \";\n}\n</style>\n</head>\n<body>\n<h1>2016ドライバーランキング</h1>\n<ul>"
repeat 40
    if firstname(cnt) = "" : break
    html_text += "<li>\n<div class=\"drivername\">" + firstname(cnt) + " " + familyname(cnt) + "</div>\n<div class=\"country\">" + country(cnt) + "</div>\n<div class=\"team\">" + teamname(cnt) + "</div>\n<div class=\"point\">" + getpoint(cnt) + "</div>\n</li>\n"
loop
html_text += "</ul>\n</body>\n</html>\n"
mesbox html_text, 640, 400

stop

となります。これを組み込んで実行してみると

ちゃんとテキストが整形されてますね。あとはこれをhtml形式で出力してあげればほぼ完成。次回はダウンロードからHTML出力まで一発で実行できるスクリプトを完成させましょう。今回はここまで。

まとめ

だいぶん完成に近づいてきました。毎度おなじみですが、今回の全コードを以下に載せておきますので、ぜひ試してみてくださいね。

//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"

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

// 初期設定
download_url = "https://www.formula1.com/en/results.html/2016/drivers.html"
sdim firstname,  40, 40
sdim familyname, 40, 40
sdim country,    40, 40
sdim teamname,   40, 40
sdim getpoint,   40, 40

lfcc "drivers.html"
notesel htmlfile
noteload "drivers.html"
first_cnt = 0 : family_cnt = 0 : country_cnt = 0 : teamname_cnt = 0
repeat notemax
    noteget text_line, cnt
    // ファーストネーム
    if (instr(text_line, 0, "hide-for-tablet") ! -1) {
        strrep text_line, "<span class=\"hide-for-tablet\">", ""
        strrep text_line, "</span>", ""
        strrep text_line, " ", ""
        //split text_line, ">", buf
        //split buf(1), "<", result
        //text_line = result(0)
        firstname(first_cnt) = text_line
        first_cnt++
        continue
    }
    // ファミリーネーム
    if (instr(text_line, 0, "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, "dark semi-bold uppercase") ! -1) {
        strrep text_line, "<td class=\"dark semi-bold uppercase\">", ""
        strrep text_line, "</td>", ""
        strrep text_line, " ", ""
        country(country_cnt) = text_line
        country_cnt++
        continue
    }

    // 所属チーム
    if (instr(text_line, 0, "grey semi-bold uppercase ArchiveLink") ! -1) {
        split text_line, ">", buf
        split buf(1), "<", result
        teamname(teamname_cnt) = result(0)
        teamname_cnt++
        continue
    }

    // 獲得ポイント
    if (instr(text_line, 0, "dark bold") ! -1) and (instr(text_line, 0, "</td>") ! -1) {
        strrep text_line, "<td class=\"dark bold\">", ""
        strrep text_line, "</td>", ""
        strrep text_line, " ", ""
        getpoint(point_cnt) = text_line
        point_cnt++
        continue
    }

loop
noteunsel

//debug
html_text = "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<meta http-equiv=\"content-language\" content=\"ja\">\n<title>2016ドライバーランキング</title>\n<style>\nbody {\ncounter-reset: drivername;\n}\nli {\ndisplay: flex;\n}\ndiv {\nmargin-right: 1rem;\n}\n.drivername, .team {\nwidth: 9rem;\n}\n.country {\nwidth: 6rem;\n}\n.drivername:before {\ncounter-increment:drivername;\ncontent:counter(drivername) \"位 \";\n}\n</style>\n</head>\n<body>\n<h1>2016ドライバーランキング</h1>\n<ul>"
repeat 40
    if firstname(cnt) = "" : break
    html_text += "<li>\n<div class=\"drivername\">" + firstname(cnt) + " " + familyname(cnt) + "</div>\n<div class=\"country\">" + country(cnt) + "</div>\n<div class=\"team\">" + teamname(cnt) + "</div>\n<div class=\"point\">" + getpoint(cnt) + "</div>\n</li>\n"
loop
html_text += "</ul>\n</body>\n</html>\n"
mesbox html_text, 640, 400

stop
スポンサーリンク

シェアする

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

フォローする