Julia ウェブスクレイピング関連

Juliaを使ったウェブスクレイピング関連のメモ.

使うパッケージは,

です. 練習として, 気象庁から, 気温データを拾ってみる.

Julia Version 1.5.0

パッケージの説明


簡単にそれぞれのパッケージの役割を確認するため, 私のHPのトップページをスクレイピング してみようと思う. ネットワーク関連には疎いので, 用語は適切ではないと思う.

一言でいうと, HTTP.jlでHTMLにアクセスし, Gumbo.jlで解析しやすい階層構造に変換し, Cascadia.jl でターゲットとなる情報を検索・抽出する.

HTTP.jl

ウェブサイトにアクセスして, HTMLをとってくるパッケージだと思う.

Julia

using HTTP
r = HTTP.get("https://koshiba.sakura.ne.jp/")

# 結果
julia> r.
	body    headers  request  status   version
julia> r.status
	200
		

HTTP.getでアクセスすると, いくつかの情報をとってきてくれる. statusが200というのは, 無事情報をとってこれたという意味だそう.

肝心な情報は, r.bodyの中に入っているので見ていく.

Gumbo.jl

HTMLをパース ( 構文解析 ) するパッケージ, とのことですが詳しくはわからない.

役割を見るほうがはやそうなのでみてみる. 先程, r.bodyにHTMLが入っていると書いたけど, 以下のように読めたもんでは ない.

Julia

julia> r.body
	2174-element Array{UInt8,1}:
	0x3c
	0x21
	0x44
	0x4f
	0x43
	  ⋮
	0x6d
	0x6c
	0x3e
	0x0a
		

ここで, Gumbo.jlのちからを借りる. parsehtmlすると, 読めるHTMLとなる.

Julia

using Gumbo
h = parsehtml(String(r.body))

# result
julia> h
	HTML Document:
	<!DOCTYPE html>
	HTMLElement{:HTML}:<HTML>
	  <head>
	    <meta charset="UTF-8"/>
	    <script async="" src="https://www.googletagmanager.com/gtag/js?id=G-FHJGK11XRK"></script>
	    <script>
	      window.dataLayer = window.dataLayer || [];
	      function gtag(){dataLayer.push(arguments);}
	      gtag('js', new Date());
	      gtag('config', 'G-FHJGK11XRK');
	        </script>
	    <meta content="width=device-width, user-scalable=yes, maximum-scale=1.0, minimum-scale=1.0" name="viewport"/>
	    <title>
	      Takahiro Koshiba's HP
	    </title>
	    <meta content="小柴孝太のHP TOP" name="description"/>
	    <link href="https://koshiba.sakura.ne.jp/src/style.css" media="screen" rel="stylesheet" type="text/css"/>
	    <script src="https://koshiba.sakura.ne.jp/src/jquery2.js"></script>
	    <script> $(function() {$("#header").load("src/header.html")});    </script>
	  </head>
	  <body>
	...
			

こうすれば, もうすでにh.rootに, htmlの内容が階層的に入っている. 例えば,h.root[1]にはheadが, h.root[2]にはbodyが入っている. そして, h.root[2][1]には, bodyの中の1つ目の要素 ( この場合は, <div id="wrapper">の内容 ) が入っている.

Julia

julia> h.root[2][1]
	HTMLElement{:div}:<div id="wrapper">
	<div id="header"></div>
	<div id="mainPhoto">
		<img alt="Top photo" height="600" src="src/top_photos/top1.jpg" width="900"/>
		<br/>
		ウズベキスタンで撮影しました. 
	</div>
	<div id="new">
		<h2>
			更新履歴
		</h2>
		2020/10/23 公開開始
		<br/>
		現在工事中
	</div>
	</div>
		

さらに, 一番下の階層までいけば, .txtを使ってテキストをとってこれる. 例えば, body[1][3][1][1]は”更新履歴”という文字を含むh2要素なので, 以下のようにして ”更新履歴”という文字列を取得できる.

Julia

julia> temp = body[1][3][1][1]
	HTML Text: `更新履歴`
julia> temp.text
	"更新履歴"
		

Cascadia.jl

Selectorという函数を駆使して, 欲しい情報を検索する. データの抽出には, juliaに附随のeachmatchなどを利用すればいいよう.

以下で具体的に使ってみる.

気象庁から気温データをとってみる


気象庁の過去の気象データのページから, 2020年1月1日, 京都, 10分毎の気温データを取得し, 可視化 してみる.

対象とするページは ココ まずは, このURLにあるHTMLをとってくる.

Julia

r = HTTP.get("http://www.data.jma.go.jp/obd/stats/etrn/view/10min_s1.php?prec_no=61&block_no=47759&year=2020&month=01&day=01&view=p1")
r = parsehtml(String(r.body))
r = r.root;
r = r[2]; # bodyの取得 ( r[1]はhead ) , 別にやらなくてもいい
		

次に, 観測データが入っているテーブルをCascadia.jlのSelectorを使ってとってくる.

テーブルには, id="tablefix1"class="data2_s"が ついているようなので, セレクタでこれを指定. 両方指定してもいいし, 片方でもいい. 指定の仕方は, Cascadiaのページの一番下にある.

最後に, テーブルの本体が格納されている場所がqs[1][1]であることを, 試行錯誤的に確認し, 取得した.

Julia

qs = eachmatch(Selector("#tablefix1"), r) # idで指定
qs = eachmatch(Selector(".data2_s"), r) # classで指定
qs = qs[1][1]
		

これで, qsにテーブル要素が入っている.

具体的にどう中身が入っているかは, qs[1], qs[2], qs[3], ...と実際にアクセスしてみたらわかると思う. それぞれが, 表の1行となっている.

for文でそれぞれのqs[i]にアクセスし, 気温データをとってくる. 具体的な数値には”data_0_0”というクラスが使われていたので, これをセレクタにした. さらに, 気温は4要素目であったので,4番目の要素を指定している.

nodeTextという函数は, 説明がないのでよくわからないが, HTMLの要素からタグの 中身を抽出するよう. 便利なのでこれを用いた. ( 先程は.txtでアクセスした. これを使う場合 もう一つ下の要素に使用する必要がある. )

ちなみに, 144は6データ/時間✕24. また, for文が3から始まっているのは, 1,2がテーブルのヘッダー であったから.

Julia

temp = zeros(144); # preallocation
for iTime in 3:146
    q = qs[iTime]
    q = eachmatch(Selector(".data_0_0"), q)[4]
    temp[iTime-2] = parse(Float32, nodeText(q));
end
		

最後に, 一応図示してみる.

Julia

using Plots
pyplot(fmt=:svg, size=(400, 250))
plot(temp)
PyPlot.savefig("kion.png", dpi=300)
		
result_kion

参考記事


参考としたのは, 基本的にそれぞれのパッケージのチュートリアル. あと, Scraping web pages with Julia and the HTTP and Gumbo packages もわかりやすい.

この記事のTOP    BACK    TOP