DuckDB で Web API を叩いて JSON をパースする話
前座
今日は12月13日の金曜日です。
そう、13日の金曜日。。。
だから、ジェイソン。。。 JSON に関する話をします!ウォー!
とはいえ、JSON で一本記事を書くのは難しかったので、DuckDB で JSON を触ってみた話(後編)をします。[1]
本題
今回は何をするの?
DuckDB でスクレイピングをします!
具体的には、WebAPI に対して、DuckDB からリクエストをして、その JSON 形式のレスポンスをテーブル化します!
実践の前の準備: 2 つ
(1)対象の Web API の説明
今回、Zenn の API を対象にします!
具体的なエンドポイントや仕様は公開されていないですが、Zenn をブラウザの開発者ツールで見られる範囲の API を叩いて検証します!
今回の対象のエンドポイントとしては、以下です。
https://zenn.dev/api/articles?username=mackey0225
結果のイメージは以下です。
{
"articles": [
{
"id": 339991,
"post_type": "Article",
"title": "Amazon Lightsail Containers は ARM アーキテクチャーとしてビルドしたコンテナイメージでは動かん!",
"slug": "mackey0225-lightsail-containers-no-arm-support",
"comments_count": 0,
"liked_count": 1,
"bookmarked_count": 0,
"body_letters_count": 2748,
"article_type": "tech",
"emoji": "🤯",
"is_suspending_private": false,
"published_at": "2024-12-07T00:00:01.790+09:00",
"body_updated_at": "2024-12-04T11:25:52.215+09:00",
"source_repo_updated_at": "2024-12-04T11:25:52.207+09:00",
"pinned": false,
"path": "/babyjob/articles/mackey0225-lightsail-containers-no-arm-support",
"user": {
"id": 99469,
"username": "mackey0225",
"name": "mackey0225",
"avatar_small_url": "https://res.cloudinary.com/zenn/image/fetch/s--1GExIj8D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/ad539edbaa.jpeg"
},
"publication": {
"id": 122,
"name": "babyjob",
"display_name": "BABY JOB テックブログ",
"avatar_small_url": "https://res.cloudinary.com/zenn/image/fetch/s--5Rx15dd7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_80/https://storage.googleapis.com/zenn-user-upload/avatar/3a89844d01.jpeg",
"avatar_url": "https://storage.googleapis.com/zenn-user-upload/avatar/3a89844d01.jpeg",
"pro": false,
"avatar_registered": true
}
},
...略...
{
"id": 333796,
"post_type": "Article",
...略...
}
],
"next_page": 2
}
ポイントとしては、記事情報のリスト articles
と次頁情報 next_page
が並んでおり、必要な記事情報がネストしている点です。
この点については、あとでも説明しますが、DuckDB で読み込むときに一手間が必要になります。
(2)DuckDB でスクレイピングする方法
DuckDB で、先に説明したエンドポイントから情報を見る方法はシンプルです。
それは、FROM
句に read_json
関数を呼び、引数に URL を書くだけです!
はい、それだけです。
サンプルとしては、以下です。
SELECT * FROM read_json('https://zenn.dev/api/articles?username=mackey0225');
SQL 実行結果
結果は少し荒いですが、 本当に簡単です。
とくに、クライアントの設定や Cookie など意識せずにリクエストを投げられるものであれば、このような形で実行できます。
上の例では、SELECT
文にしていますが、テーブルに突っ込んで、様々なクエリで分析することができます。
いざ、実践!!
DuckDB を立ち上げて、以下の SQL を実行します!
SELECT
article.*
FROM (
SELECT
unnest(articles) as article
FROM
read_json_auto(
'https://zenn.dev/api/articles?username=mackey0225',
ignore_errors=true
)
);
上記のクエリを実行するとー、、、
SQL 実行結果
記事の一覧が表示できましたねー。
SQL の説明
本記事の前編にあたるDuckDB で 入れ子になっている JSON を UNNEST する話で紹介している unnest
を使って、記事情報の配列を UNNEST して展開しています。
また、JSON を取得する関数を read_json_auto
にすることで、スキーマ定義が不要になります。(非常に簡単!)
まとめ
今回、DuckDB で JSON 形式のレスポンスがある Web API に対して、スクレイピングする方法を簡単に紹介させていただきました。
個人的にも DuckDB は面白く、今回のような簡単にテーブルにしたり、SQL ライクなクエリでデータ分析したりするのが簡単にできます。
自分としてはまだまだ使いこなせていないので、また面白く便利な機能があれば、まとめていきたいです。[2]
-
今月も他にAWS CloudShell に DuckDB を入れて、ALB のログを見てみたという記事も公開しているので、興味があれば見てもらえると嬉しいです。 ↩︎
私たち BABY JOB は、子育てを取り巻く社会のあり方を変え、「すべての人が子育てを楽しいと思える社会」の実現を目指すスタートアップ企業です。圧倒的なぬくもりと当事者意識をもって、こどもと向き合う時間、そして心のゆとりが生まれるサービスを創出します。baby-job.co.jp/
Discussion