ElixirでQiitaAdventCalendarの執筆者リストを作る
intro
この記事は、「Elixir Advent Calendar 2022」その1の9日目の記事です。
8日目は @Yoosuke さんの「Elixir × GraphQLシリーズ① ~ サクッとGraphQLサーバーのセットアップ ~」でした!
概要
今年のElixirのAdvent Calendarはスゴイ勢いですね!
カレンダーが9つもあり、どれもほとんど埋まっていて大盛況です。
今回はQiitaのAdventCalenderの執筆者を数えるプログラムをElixirで作ってみました。
リポジトリ
こんなプログラム
実装は下記のようになっています。
単純にQiitaのアドベントカレンダーのページを取得してユーザー情報の部分だけ抜き出してカウントしています。
記事を投稿しているかどうかに関わらず枠予約されていればカウントします。
defmodule QiitaAdventCalendarUserCounter do
import Meeseeks.CSS
@spec run(Calendar.year()) :: map()
def run(year \\ Date.utc_today().year, language \\ "elixir") do
request_body("https://qiita.com/advent-calendar/#{year}/#{language}", 0)
|> Meeseeks.parse()
|> Meeseeks.fetch_all(css(".css-1covvrn .css-15wswuq .css-h63oov"))
|> elem(1)
|> Enum.map(fn x -> Meeseeks.text(x) |> String.replace(" ","") end)
|> Enum.frequencies
|> Enum.sort
end
defp request_body(_, 10), do: "over retry challenge count!"
defp request_body(target_url, retry_count) do
result = HTTPoison.get!(target_url)
case result.status_code do
200 ->
result.body
_ ->
:timer.sleep(1000)
request_body(target_url, retry_count + 1)
end
end
end
defmodule QiitaAdventCalendarUserCounter.MixProject do
use Mix.Project
def project do
[
app: :qiita_advent_calendar_user_counter,
version: "0.1.0",
elixir: "~> 1.13",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
]
end
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:httpoison, "~> 1.8"},
{:meeseeks, "~> 0.16.1"}
]
end
end
解説
簡単なプログラムなので特に解説することもありませんが、QiitaのAdventCalendarのページを取得してきてMeeseeksライブラリでパースしたり必要な要素を取り出して Enum.frequencies/1
でキー名(= アカウント名)ごとに件数を数えています。
MeeseeksはHTML/XMLパーサです。Elixirではこの手のライブラリはFlokiが有名ですが、今回は勉強も兼ねてMeeseeksを使いました。
MeeseeksとFlokiの比較はMeeseeksが作ったドキュメントがあります。
他には、QiitaAdventCalendarUserCounter.run/2
に年と言語を指定すれば過去のカレンダーや他の言語のカレンダーを調べることも可能です。
年は2021年まで対応できているのを確認しています(それ以前はDOM構造が変わっているためパース失敗)
結果
※ 結果は 2022年12月9日現在のものです
iex(1)> QiitaAdventCalendarUserCounter.run()
[
{"@Alicesky2127", 27},
{"@GKBR", 1},
{"@GeekMasahiro", 8},
{"@Goody27", 1},
{"@Gsann", 1},
{"@MzRyuKa", 1},
{"@RyoWakabayashi", 46},
{"@ShigeItoEx", 7},
{"@ShozF", 2},
{"@Yoosuke", 8},
{"@a_utsuki", 1},
{"@def_elixir", 1},
{"@gx3n-inue", 1},
{"@hiro_1107", 1},
{"@hisaway", 1},
{"@k-j-y", 2},
{"@kikuyuta", 1},
{"@koga1020", 3},
{"@koyo-miyamura", 1},
{"@kyawaguchi", 1},
{"@miwacchi", 5},
{"@mnishiguchi", 34},
{"@mokichi", 1},
{"@myasu", 1},
{"@nako_sleep_9h", 28},
{"@nanbut14", 1},
{"@naritomo08", 2},
{"@ohr486", 1},
{"@piacerex", 25},
{"@pojiro", 1},
{"@t-kurasawa", 1},
{"@t-yamanashi", 8},
{"@ta_to_jp", 2},
{"@tamanugi", 1},
{"@the_haigo", 13},
{"@tomoaki-kimura", 1},
{"@torifukukaiou", 45},
{"@tuchiro", 1},
{"@westbaystars", 3},
{"@zacky1972", 26}
]
まとめ
ElixirでQiita AdventCalendarの執筆者リストを出力してみました。
大勢の方が参加されていることが具体的な数値で分かってElixirの人気っぷりが分かりますね!
明日は @t-yamanashi さんの「Elixirで音を鳴らして遊ぼう」です!お楽しみに!
Discussion