スクレイピングとは?curlで簡単なスクレイピングを試す。その2

スクレイピングとは?curlで簡単なスクレイピングを試す。その2

前回のスクレイピング記事でお話した続き。
今回は実際の加工をやっていく話。
今はpythonの方が主流っぽいですが、ぶっちゃけpythonはやったことないのでshellでごりごり書いていきます。

前回の復習

まずはHTML情報を持ってくる方法
curl + ‘スクレイピングしたいサイトのURL’
で可能。

curl 'https://www.data.jma.go.jp/obd/stats/etrn/view/monthly_h1.php?prec_no=40&block_no=00&year=2017&month=1&day=&view=' > hoge

何度も叩くと負荷をかけてしまうので、一旦hogeに書き出す。

続いて、欲しい情報の部分だけタグのidやclassを基に切り出す。

cat hoge | tr -d '\n' | sed -e 's/.*//g' | sed -e 's/<\/table>.*//g' > fuga

以前の記事ではここまでやった。
続いて、ここから欲しい情報まで加工していく。

全部足して平均を出す。

例えば茨城の平均降水量が知りたい場合、
恐らく全地域の温度を足して平均を出すのが正しいだろう。
そのために、まずわかりやすい形に整形する。
見やすい形にするのであれば、

地域名 水戸
1月 10度
2月 20度

↑こんな形にするのがよさそう。
ということで、以下のコマンドをたたく。

 

$ cat fuga | sed -e 's/<.td>/,/g' | sed -e 's/<.tr>/\n/g' | sed -e 's/<[^>]*>/ /g'
  月  花園  北茨城  大子  笠間  水戸*  古河  下妻  坂東  土浦  鹿嶋  江戸崎  日立  柿岡  美野里  龍ケ崎  中野  徳田  鉾田  常陸大宮  門井  大能  つくば(館野)*  下館  高萩  常総
    1  , 57.5, 51.0, 9.0, 11.5, 17.5, 19.0, 13.5, 19.5, 21.5, 55.5, 40.0, 41.5, 13.5, 22.5, 34.5, 8.5, 24.0, 36.5, 10.0, 12.5, 42.5, 16.0, 11.5, 35.5, 15.5,
    2  , 25.5, 13.0, 17.0, 21.5, 23.5, 11.5, 13.5, 15.0, 22.5, 34.5, 26.0, 22.0, 21.5, 25.0, 19.0, 21.5, 16.5, 41.0, 15.5, 12.0, 26.5, 21.0, 14.0, 20.0, 18.0,
    3  , 96.5, 77.5, 38.5, 82.5, 76.0, 66.5, 66.0, 66.5, 83.0, 141.0, 104.0, 87.0, 69.0, 88.5, 91.5, 53.0, 58.5, 116.5, 45.5, 55.5, 76.0, 72.5, 62.0, 79.0, 68.0,
    4  , 170.0, 120.0, 124.5, 95.0, 112.5, 69.5, 86.5, 81.5, 102.5, 128.5, 109.0, 110.5, 109.0, 100.0, 111.5, 97.0, 128.5, 124.5, 106.5, 67.0, 183.0, 102.5, 83.0, 129.5, 92.0,
    5  , 154.0, 86.0, 72.0, 96.5, 95.5, 51.5, 51.5, 51.5, 69.5, 75.5, 66.5, 91.5, 81.5, 66.5, 51.0, 77.0, 80.5, 86.0, 82.0, 51.0, 142.0, 66.0, 54.0, 80.5, 51.0,
    6  , 170.5, 189.5, 118.0, 100.0, 55.5, 64.5, 59.5, 44.0, 45.0, 71.0, 60.0, 95.0, 67.5, 38.5, 72.0, 72.5, 122.5, 52.5, 92.5, 57.5, 126.5, 51.0, 76.0, 134.0, 54.5,
    7  , 159.0, 88.5, 196.0, 116.0, 104.0, 146.5, 163.5, 218.5, 152.5, 111.0, 74.0, 84.5, 245.5, 147.5, 101.0, 81.5, 157.5, 115.0, 266.5, 108.0, 223.0, 110.5, 246.5, 83.5, 218.5,
    8  , 196.5, 84.0, 124.5, 102.0, 123.5, 139.5, 82.0, 104.0, 83.5, 83.5, 80.5, 64.5, 147.0, 99.5, 74.5, 70.5, 112.5, 95.0, 69.5, 130.5, 129.0, 116.0, 95.0, 62.5, 73.5,
    9  , 247.0, 184.0, 114.5, 138.0, 126.0, 113.0, 148.0, 162.0, 167.0, 184.0, 156.0, 196.0, 165.5, 157.0, 156.0, 153.5, 156.5, 164.0, 102.5, 103.5, 254.0, 177.0, 128.5, 176.0, 163.0,
    10  , 455.0, 306.5, 290.0, 341.5, 332.5, 368.5, 346.5, 391.5, 365.0, 454.5, 434.0, 327.0, 399.5, 367.5, 389.0, 325.0, 261.0, 415.5, 291.5, 309.0, 383.0, 415.5, 358.5, 319.5 ), 375.0,
    11  , 48.5, 39.5, 41.5, 40.5, 39.5, 22.0, 23.5, 29.5, 49.0, 64.5, 51.5, 32.0, 47.0, 37.0, 56.0, 40.0, 54.0, 38.5, 44.0, 34.5, 54.5, 44.5, 33.0, 34.0, 30.5,
    12  , 31.0, 19.5, 22.0, 14.0, 20.5, 11.0, 12.5, 14.5, 10.0, 26.5, 14.0, 23.5, 13.0, 14.5, 14.0, 18.5, 26.0, 19.5, 22.5, 14.0, 33.0, 8.5, 14.5, 26.0, 14.0,

テーブルタグを使っている場合、

が目的の値が入っている部分なので、そこをまず,区切りに変更。

タグが列になるのでそこで改行を入れ、その後いらない全タグを消去する。

そしたら、awkを使って見出し以外の数値を足して割ってあげればよい。

$ cat fuga | sed -e 's/<.td>/,/g' | sed -e 's/<.tr>/\n/g' | sed -e 's/<[^>]*>/ /g' | awk -F',' '{total=0;} NR!=1{for(i=1;i<=NF;i++){total+=$i}} NR!=1{print total/(NF-1)}'
24.6538
19.9615
73.9808
105.692
74.4423
80.6154
143.288
98.1154
153.904
347.385
40
18.0385

まず一行目は見出しなので、NR!=1で計算と表示をはじく。
(※ awkでNRとは、改行区切りで何行目かを指す。)
そして見出し項目を含めず平均を取るため、NF-1で割る。
(※ awkでNFは、その行を区切り文字で区切って何カラムあったかを指す。)

これで茨城県の平均降水量を取ることができた。
実際に使う場合は、Excelなどでいくつか検算をしてから使うと良いだろう。
最高気温等の場合は、夏が30度を超えるかなどのざっくりした見方でも問題ないかもしれない。

まとめ

情報量が多くなってしまったので、前後編に分けてみた今回。
スクレイピングの記事は多くないので、
(実際あまり良いことではないので)
誰かのお役に立てると嬉しい。