
今回は前回調べた2016年のRaceresult(オーストラリアGP)のダウンロードと必要なデータの取り出しをHSPにてプログラミングしてみたいと思います。
今回の目的は
- 以前つくったHSPのプログラムを再利用してデータを取り出す
です。では、いってみましょう!
以前つくったHSPを利用する
ダウンロードやデータの取り出し、文字コード(改行コードの変換)などは以前作ったプログラムを活用したいと思います。詳しい説明は
こちらでどうぞ!
download_urlを変更する
以前に調べていたグランプリ結果のurl(ここでは2016年のオーストラリアグランプリの結果)をdownload_urlに設定します。
https://www.formula1.com/en/results.html/2016/races/938/australia/race-result.html

データを格納する入れ物を追加
新たに
- 着順
- カーナンバー
- 周回数
- タイム(タイム差、ラップ差、リタイア)
この4つを格納する入れ物を用意します。それぞれ以下のような感じにしました。
sdim position, 40, 40 sdim carnumber, 40, 40 sdim laps, 40, 40 sdim times, 40, 40
データ抽出部分の追加・変更
今回の最大のポイントであるデータ抽出部分の追加や変更です。前回調べた通り
<tr>
<td class="limiter"></td>
<td class="dark">1</td>
<td class="dark hide-for-mobile">6</td>
<td class="dark bold">
<span class="hide-for-tablet">Nico</span>
<span class="hide-for-mobile">Rosberg</span>
<span class="uppercase hide-for-desktop">ROS</span>
</td>
<td class="semi-bold uppercase hide-for-tablet">Mercedes</td>
<td class="bold hide-for-mobile">57</td>
<td class="dark bold">1:48:15.565</td>
<td class="bold">25</td>
<td class="limiter"></td>
</tr>
trタグで囲まれた中身にに必要なデータが入ってます。また、条件としては
- trタグに囲まれた範囲である
- 着順:「”dark”」
- カーナンバー:「dark hide-for-mobile」
- ドライバー名:「”hide-for-tablet”」「”hide-for-mobile”」「”uppercase hide-for-desktop”」
- ラップ数:「bold hide-for-mobile」
- タイム:「dark bold」に加えて後ろに文字があるか否かで判定
- ポイント:「”bold”」
という風に考えてました。これをさらに正確に合致する条件として書き直すと
- trタグに囲まれた範囲である
- 着順:<td class=”dark”>がある事
- カーナンバー:<td class=”dark hide-for-mobile”>がある事
- ドライバー名:ファーストネームは<span class=”hide-for-tablet”>、ファミリーネームは<span class=”hide-for-mobile”>がある事
- ラップ数:<td class=”bold hide-for-mobile”>がある事
- タイム(タイム差、ラップ差、リタイア):<td class=”dark bold”>があり、さらに</td>もある事
- ポイント:<td class=”bold”>がある事
実際にはtrタグで囲まれたという判定部分は省略可能っぽいですね。この条件でデータを取り出していきたいと思います。hspでの判定方法はinstrを使います(詳しくはここ)。
実際にコードにしてみる
そうそう。あと必要なのは
- それぞれのデータ格納回数を数えるカウンターの用意
でした。では、上の条件を踏まえた上で、実際に書いてみましょう。
lfcc url_pagename
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
「strrep」は置換して不要なものを消す作業を、splitは該当する文字で1文を切り分ける作業をして、必要なデータ部分のみを取り出しています。それぞれ
- 着順→position(数字0~40)
- カーナンバー→carnumber(数字0~40)
- ファミリーネーム→familyname(数字0~40)
- ファーストネーム→firstname(数字0~40)
- 所属チーム→teamname(数字0~40)
- ラップ→laps(数字0~40)
- タイム→times(数字0~40)
- 獲得ポイント→getpoint(数字0~40)
に格納されます。これを使って次回はHTMLを作成しましょう。
まとめ
ひとまず今回はここまで。ここまでのコードを載せておきますね。次回はHTMLとcsv出力をしてみたいと思います。
//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/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
/* 第一回で作成したダウンロード部分 */
// 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"
}
// チェック用分岐
goto *skippoint
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
/*データ抽出部分*/
lfcc url_pagename
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
stop