#はじめに
科学計算向けスクリプト言語「Julia(JuliaLang)」の利点の一つは、
データ前処理と統計処理、そしてその結果のレポートを、Pythonと同じように一貫して行える事にあります。
そして、Juliaは多くのケースでPythonよりも早いと言われています。
しかし、Juliaの最新バージョンは0.4であり、
ライブラリが出揃っている状態ではなく、又、ライブラリの情報も知れ渡っているものではありません。
今回は、JuliaでWebスクレイピング(Webページからデータを抽出する事)に使えそうなライブラリを調べてみました。
(Beautiful SoupをPyCall.jlで使う方法も考えましたが、今回は紹介しません)
#01.Webページをダウンロードする。 [Requests.jl, HttpCommon.jl]
Requests.jlの関数「get(URI, クエリ文字列)」でWebページをダウンロードします。
その際、HttpCommon.jlの関数「encodeURI(エンコード前の文字列)」でWebページのURIをエンコードしておきます。
getの返り値のメンバー変数「data」からソースコードを読み取ります。
Pkg.add("Requests")
Pkg.add("HttpCommon")
using Requests
using HttpCommon
request = get("http://www.nicovideo.jp/search/" * encodeURI("東方project"), query = {:hft => "0", :itc => "1", :ct => "2", :cip => "1"})
code = request.data
#02.Webページのソースコードを解釈する。[Gumbo.jl]
Gumbo.jlのparsehtml(HTMLの文字列)でソースコードを解釈します。
Gumbo.jlはHTML構文解析ライブラリGumbo(Google製)のJuliaラッパーです。
Pkg.add("Gumbo")
using Gumbo
doc = parsehtml(code)
#03.指定要素を取得する。
Gumbo.jlで要素を取得する方法は、
ジャグ配列(配列の配列)として指定する方法とイテレーターの中で指定する方法の2つがあります。
CSSセレクターやXPathのような高度な指定方法はないようです。
elem = doc.root[2][7][1]
elem
# => HTMLElement{:div}:
# <div class="inner"> ……
for elem in preorder(doc.root)
if isa(elem, HTMLElement)
#タグの場合
#(特になし)
elseif isa(elem, HTMLText)
#テキストの場合
println(elem.text)
# => キーワードで動画検索
# niconico ……
end
end
※イテレーター自体の指定方法はpostorder(前から)・preorder(後ろから)・breadthfirst(幅優先)の3つがあります。
#04.指定要素を判別し、値を取得する。
要素にはHTMLElement(タグ)とHTMLText(テキスト)の2種類の型があるようです。
それぞれの型で値を取得する方法は違っています。
#タグ名を取得
tag(elem)
# => ;div
#属性一覧を取得
elem.attributes
attrs(elem)
# => Dict{String,String} with 1 entry:
# "class" => "inner"
#子要素一覧を取得
elem.children
children(elem)
# => 2-element Array{HTMLNode,1}:
# HTMLElement{:div}
# HTMLElement{:div}
#親要素一覧を取得
elem.parent
# => HTMLElement{:section}:
# <section class="tagCaption"> ……
#属性を取得
getattr(elem, "class")
# => "inner"
#属性を設定
setattr!(elem, "id", "divInner")
# => "divInner"
txt = doc.root[2][7][1][1][1][1][1][1]
#テキストを取得
txt.text
# => "Example text"
#終わりに
PythonのBeautiful Soupのような高度なHTMLパーサーが欲しい所です。