スクレイピング(3):Qiitaの検索ページからJuliaタグ最新記事のリンクとタイトルを取得

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

初めに

 前回のスクレイピング(2)で、QiitaのJuliaタグページから、リンクとタイトルを取得しました。

 この記事を書いた時点(2022/3/29)では、feedで公開された記事は20件でした。ところが2022/4/7以降、feedでは4件のみの公開になっています。内部での設定を変更したようです。そもそもfeedはwebにアクセスしなくても更新情報を取得できるようにし、それによって記事への動線を確保するためのものです。4件では1日の新着分にすらならないので、新着記事に到達することができません。何のためにこういう変更したのか訳が分かりません。(怒)

 そこで今回は、上記のfeedを使わずに、juliaタグの新着記事を取得する方法を紹介します。
 基本的には、次の記事に沿った方法と同じになりますが、当然ながら、URLやHTMLタグなどの指定が異なります。

 なお、今回対象とするのは、「juliaタグが付いた記事を検索した結果を新着順に表示したページ」になります。1ページに10件が掲載されているので、新着20件を取得するために、2ページ目も取得対象とします。取得数を増やしたければ、URL中の「page=」の値を増やせば対応可能です。
 このページは、HTMLのなかにURLとタイトルが表示されているので、通常のスクレイピングで情報が取得できます。

使用するパッケージ

パッケージの追加

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

julia> using Pkg
julia> Pkg.add("HTTP")
julia> Pkg.add("Gumbo")
julia> Pkg.add("Cascadia")
julia> Pkg.add("URIs")

HTMLの取得

 指定URLからHTMLファイルを取得します。以下、1ページ目の取得についての説明を行います。
 また、基本的な操作は以前の記事と同じなので、適宜省略します。

julia> using HTTP
julia> qiita_search_url = "https://qiita.com/search?q=tag%3Ajulia&sort=created"
julia> response = HTTP.request("GET", qiita_search_url)
julia> code = String(response.body)              # Byte列を文字列に変換

HTMLファイルの解析

 取得したHTMLを解析し、「head」タグと「body」タグを切り出します。

julia> using Gumbo
julia> doc = Gumbo.parsehtml(code)
julia> head = doc.root[1]
julia> body = doc.root[2]

CSSセレクターを用いた検索

 CSSセレクターを使ってHTMLから必要な情報を検索します。

 リンクを取得するので「a」タグの指定で検索できそうですが、本来必要としない情報まで含まれてしまいます。対象ページのHTMLソースを見ると「h1」タグの直下の「a」タグで、見出しとURLを取得できそうです。(HTMLの構造は、将来変更になる場合があります)

julia> using Cascadia
julia> qs = eachmatch(Selector("h1 a"), body)

 変数qsに、aタグの一覧が格納されています。この時点では、タグのすべての記述を含んでいるので、必要な情報のみを抜き出します。

 リストに格納されているので、for文で1件ずつ処理しています。1件のデータは次のようになっています。

julia> s = qs[1]
HTMLElement{:a}:<a href="/dnkit/items/8bfa4cad2cf3729fae37">
  CUDAとプロセス並列化で爆速画像処理 with Julia
</a>

 まず、URLを抜き出します。これは、aタグのhref属性の値を取得することに該当します。万が一、href属性がなかった場合に備え、ここではnothingを設定するように指定しておきます。(特定のURL、例えば404ページのURLなどを指定することもありそうです。)

julia> url = getattr(s, "href", nothing)
"/dnkit/items/8bfa4cad2cf3729fae37"

 次に見出しを抜き出します。「nodeText()」を使って、タグ中のコンテンツとしての文字列を取得します。

julia> title = nodeText(s)
"CUDAとプロセス並列化で爆速画像処理 with Julia "

URLの補正

 URLがいわゆる相対パスになっています。このままでは、不都合なので、URLを合成して絶対パスを作成します。

julia> using URIs
julia> qiita_search_url = "https://qiita.com/search?q=tag%3Ajulia&sort=created"
julia> new_url = resolvereference(qiita_search_url, url)
URI("https://qiita.com/dnkit/items/8bfa4cad2cf3729fae37")
julia> url_str = "$new_url"
"https://qiita.com/dnkit/items/8bfa4cad2cf3729fae37"

まとめ

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

julialangjp/ScrapingQiitaSearchByJulia (Github)

参考記事

コメント

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