スクレイピング(2):QiitaのJuliaタグページのFeedからリンクを取得

技術
この記事は約5分で読めます。

初めに

 今回のスクレイピング対象は、QiitaのJuliaタグページです。

Julia – Qiita

 当初は、Zennの場合と同様に、HTMLから見出しとリンクを抜き出すことを考えました。
 しかし、HTMLソースを見てみると、画面に表示されている「最近の投稿」に相当する情報が見当たりません。どうやら、Javascriptで動的に生成しているようです。(想像)

 これでは、HTMLソースを取得して解析する方法が使えません。PyCall+selenium を使ってブラウザにJavascriptを解釈させて、DOMに展開された状態で処理する方法もありますが、今回は、Julia言語だけで処理することにします。

 Qiitaでは、タグページにはフィードが提供されていて、新着記事の見出しやリンクの情報が含まれています。

Juliaタグがつけられた新着記事 – Qiita

 フィードを解析するパッケージがあれば簡単なのですが、見つけられなかったので、XMLデータとして扱い、必要な情報を抜き出します。

使用するパッケージ

パッケージの追加

 必要なパッケージを追加します。

julia> using Pkg
julia> Pkg.add("HTTP")
julia> Pkg.add("EzXML")

フィードの取得

指定URLからフィード(XMLファイル)を取得します。

julia> using HTTP
julia> qiita_feed = "https://qiita.com/tags/julia/feed"
julia> response = HTTP.request("GET", qiita_feed)
julia> code = String(response.body)              # Byte列を文字列に変換

 HTTPステータスコードが200のときに取得に成功したとみなします。

julia> response.status
200

XMLファイルの解析

 取得したXMLを解析します。
 文字列を解析した結果は EzXML.Document型で格納されます。

julia> using EzXML
julia> doc = parsexml(code)
julia> typeof(doc)
EzXML.Document

 doc変数にEzXML.Document型が格納されています。
 XMLのrootを抜き出します。対象のXMLファイルでrootに相当するタグは「feed」です。これでフィード本体の情報を取得することができました。

julia> feed = root(doc)

 「feed」タグ以下の情報を含んだEzXML.Node型のデータが得られました。

julia> typeof(feed)
EzXML.Node

フィードの要素を順にチェックします

 HTMLの時のようにCSSセレクターを使えないので、要素を一つ一つ確認しています。
 「feed」タグの下に、複数の「entry」タグがあります。これがそれぞれの記事の情報を示しています。今回取得するのは、「entry」タグの下の「url」タグと「title」タグの内容です。
 HTMLの場合のように深い階層構造になっていないので、一つ一つを確認してもそれほど大変な処理にはなりません。

 次のコードで、見出しとリンクのタプルを要素とするリストが作成されます。もう少し効率の良い書き方があるかもしれませんが、わかりやすさを優先しました。

julia> begin
           list = []
           for tag in eachelement(feed)
               if tag.name == "entry"
                   url = nothing
                   title = nothing
                   for item in eachelement(tag)
                       if item.name == "url"
                           url = item.content
                       elseif item.name == "title"
                           title = item.content
                       end
                   end
                   if !isnothing(url)
                       pair = (title, url)
                       push!(list, pair)
                   end
               end
           end
       end
julia> 

 なお、フィードに書き込まれるURLは絶対パスなので、Zennの時のようなURLの補正の処理は不要です。

まとめ

上記をまとめたコードを下記に公開しています。
実行すると、日付付きのファイルにTSV形式で見出し+URLを出力します。

julialangjp/ScrapingQiitaTagByJulia (Github)

参考記事

コメント

タイトルとURLをコピーしました