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

f1 site no.44

前回ではダウンロードからHTML作成までトータルで実行できるプログラムにしました。今回はそれを改良していきます。

HSPでF1ポイントのランキングページを生成してみる~その5~【HSP活用術】
前回ではhtml用のテキストを作成しました。今回はダウンロードからHTML作成までトータルで実行できるプログラムに仕上げましょう。 ...

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

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

改良してみよう

今の状態ではどのレースまで終了した時点のランキングなのかがわからないので、それを表示するように変更。さらに、レース終了してあたらしいランキングになった場合には別名で保存されるように改良していきたいと思います。ファイル名については

  • グランプリ名+_finished.html

というルールにします。さて、まずは2016年のF1スケジュールを公式サイトから抽出して、日時をデータ化しましょう。

2016 FIA Formula One World Championship® Race Calendar

上記のページを開いて、chromeの検証からコンソールから以下のスクリプトを実行します。

var a_list = document.getElementsByClassName('teaser-date');
var b_list = document.getElementsByClassName('teaser-info-title');
for(i=0; i<a_list.length; i++){
console.log(a_list[i].innerText);
console.log(b_list[i].innerText);
}

結果は

18 - 20 MAR
2016 FORMULA 1 ROLEX AUSTRALIAN GRAND PRIX
01 - 03 APR
2016 FORMULA 1 GULF AIR BAHRAIN GRAND PRIX
15 - 17 APR
2016 FORMULA 1 PIRELLI CHINESE GRAND PRIX
29 APR - 01 MAY
2016 FORMULA 1 RUSSIAN GRAND PRIX
13 - 15 MAY
FORMULA 1 GRAN PREMIO DE ESPAÑA PIRELLI 2016
26 - 29 MAY
FORMULA 1 GRAND PRIX DE MONACO 2016
10 - 12 JUN
FORMULA 1 GRAND PRIX DU CANADA 2016
17 - 19 JUN
2016 FORMULA 1 GRAND PRIX OF EUROPE
01 - 03 JUL
FORMULA 1 GROSSER PREIS VON ÖSTERREICH 2016
08 - 10 JUL
2016 FORMULA 1 BRITISH GRAND PRIX
22 - 24 JUL
FORMULA 1 MAGYAR NAGYDÍJ 2016
29 - 31 JUL
FORMULA 1 GROSSER PREIS VON DEUTSCHLAND 2016
26 - 28 AUG
2016 FORMULA 1 BELGIAN GRAND PRIX
02 - 04 SEP
FORMULA 1 GRAN PREMIO HEINEKEN D'ITALIA 2016
16 - 18 SEP
2016 FORMULA 1 SINGAPORE AIRLINES SINGAPORE GRAND PRIX
30 SEP - 02 OCT
2016 FORMULA 1 PETRONAS MALAYSIA GRAND PRIX
07 - 09 OCT
2016 FORMULA 1 EMIRATES JAPANESE GRAND PRIX
21 - 23 OCT
2016 FORMULA 1 UNITED STATES GRAND PRIX
28 - 30 OCT
FORMULA 1 GRAN PREMIO DE MÉXICO 2016
11 - 13 NOV
FORMULA 1 GRANDE PRÊMIO DO BRASIL 2016
25 - 27 NOV
2016 FORMULA 1 ETIHAD AIRWAYS ABU DHABI GRAND PRIX

こんな感じに抽出できます。このデータを利用して以下のようなテキストを作成。

3/20,AUSTRALIAN GRAND PRIX
4/3,BAHRAIN GRAND PRIX
4/17,CHINESE GRAND PRIX
5/1,RUSSIAN GRAND PRIX
5/15,SPAIN GRAND PRIX
5/29,MONACO GRAND PRIX
6/12,CANADA GRAND PRIX
6/19,EUROPE GRAND PRIX
7/3,AUSTRIA GRAND PRIX
7/10,BRITISH GRAND PRIX
7/24,HUNGARY GRAND PRIX
7/31,GERMANY GRAND PRIX
8/28,BELGIAN GRAND PRIX
9/4,ITALIA GRAND PRIX
9/18,SINGAPORE GRAND PRIX
10/2,MALAYSIA GRAND PRIX
10/9,JAPANESE GRAND PRIX
10/23,USA GRAND PRIX
10/30,MEXICO GRAND PRIX
11/13,BRASIL GRAND PRIX
11/27,ABU DHABI GRAND PRIX

これをf1carendar.txtとして保存しておきます。
HSPでこれを読み込んで、現在の日時と比較してどのレース終了時点なのかを事前に格納していきましょう。コードは

// f1カレンダーチェック
month = gettime(1)
day = gettime(3) + month * 40
racename = ""
notesel a
noteload "f1calendar.txt"
repeat notemax
    noteget text_line, cnt
    split text_line, ",", result
    split result(0), "/", chk_mm, chk_dd
    chkday = int(chk_dd) + int(chk_mm) * 40
    if day > chkday {
        racename = result(1)
    } else {
        break
    }
loop

こんな感じでしょうか。dayに今日の日付けと月×40を入れて、カレンダーの月日(chkday)も同じ計算式にして、両者を比較。chkdayが大きくなった時点より一つ前のレース名を取り出しています。

html内に終了時点の一文を追加する

これをダウンロード~html生成に組み込んでファイル名やhtml本体に表示させます。表示位置はランキングの下に※印入りで付け加えます。スクリプトの最後の方にある

html_text += "</ul>\n</body>\n</html>\n"

html_text += "</ul>\n<p>※" + racename + " 終了時点のランキングです</p></body>\n</html>\n"

に変更します。確認してみると

add line

ちゃんと反映されていますね。

保存するhtmlファイル名を変更する

ファイル名はスクリプト最後の方の

notesave "driverspoint.html"

これを書き換えればOK。ルールは

  • グランプリ名+_finished.html

だったので、これに沿ったコードに変更しましょう。

notesave racename+"_finished.html"

make file name

ちゃんとグランプリ名+_finished.htmlに変わってますね。これでレース終了ごとに違うファイル名になるのでシーズン通して終了時点でのランキングhtmlが生成できるようになりました。

まとめ

これで一応完成です。他にもいろいろな改良ができるかと思います。ドライバーポイントの折れ線グラフを表示するのも面白かもしれませんね。
全スクリプトを下記に公開しておきますので、お試しくださいませ。とはいっても2016シーズンのみ対応なので期限がありますが…。

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

// f1カレンダーチェック(第6回作成部分)
month = gettime(1)
day = gettime(3) + month * 40
racename = ""
notesel a
noteload "f1calendar.txt"
repeat notemax
    noteget text_line, cnt
    split text_line, ",", result
    split result(0), "/", chk_mm, chk_dd
    chkday = int(chk_dd) + int(chk_mm) * 40
    if day > chkday {
        racename = result(1)
    } else {
        break
    }
loop


/* 第一回で作成したダウンロード部分 */

// 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
mes "ERROR "+estr
stop

*comp
mes "DOWNLOAD 完了"
//stop



/*html生成部分(2~5回で作成)*/

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

//make_html
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: 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>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"
html_text += "</ul>\n<p>※" + racename + " 終了時点のランキングです</p></body>\n</html>\n"


nkfcnv html_text,html_text,"Sw"

notesel html_text
//notesave "driverspoint.html"
notesave racename+"_finished.html"
noteunsel
await 1
dialog "save html file"
//mesbox html_text, 640, 400

end
stop
スポンサーリンク

シェアする

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

フォローする