32
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SwiftAdvent Calendar 2021

Day 25

Qiita Advent Calendar 2021 に登録された記事は Qiita公開 と Zenn公開 のどちらが多かったか?【Swift でスクレイピング】

Last updated at Posted at 2021-12-24

記事初出時点では2021年12月24日までの情報でしたが、2021年12月25日までの情報を反映させました。

README_image.png

アドベントカレンダーにはどのような記事を紐付けていいのですか?
Qiita Advent CalendarにはQiitaはもちろんZennやnote、はてなブログ、個人ブログなど、エンジニアに関わる内容であればどのサイトの記事でも歓迎です。

Qiita Advent Calendar について | Qiita Support https://help.qiita.com/ja/articles/qiita-adcal-1#faq

さて、今年の Qiita Advent Calendar の記事の公開先は「Qiita で公開」と「Zenn で公開」のどちらが多かったのでしょうか?

実装方法など

本記事をお読みの方は何よりも結果を先に知りたいかと思いますので、このために作成したプログラムなどについては記事末尾にまとめて記載します。キーワードだけ列挙しておきます。

Swift, Swift Concurrency, SwiftUI, Combine, Xcode 13.2, Swift Playgrounds 4
iOS App, iPadOS App, macOS Command Line Tool, Swift Package, Kanna

  

注意点

後述しますが、Qiita Advent Calendar 2021 のカレンダー数は約 700 であり、それらすべてにアクセスしてスクレイピングを行いました。ソフトウェアを開発・実行するときは以下に注意して行いました。

利用制限
認証している状態ではユーザごとに1時間に1000回まで、認証していない状態ではIPアドレスごとに1時間に60回までリクエストを受け付けます。

Qiita API v2ドキュメント - Qiita:Developer https://qiita.com/api/v2/docs

そのため、すべてのデータの取得タイミングに60秒の間隔がありますので、タイミングによっては以下に示した結果が現在の状況を示していない場合があります。
(実行期間: 2021年12月24日10時33分ごろ 〜 2021年12月24日22時58分ごろ  つまり2021年12月25日公開の記事が含まれていません)
(2021年12月25日までの情報を反映させました  実行期間: 2021年12月26日0時33分ごろ 〜 2021年12月26日14時47分ごろ)

結果(全体)

全体.png

ドメイン 記事数 割合
qiita.com 7760 60.3%
zenn.dev 888 6.9%
note.com 720 5.6%
medium.com 129 1.0%

Qiita公開 のほうが多い

Qiita で公開のほうが多かった

というわけで、今年の Qiita Advent Calendar は、Qiita で公開された記事数が Zenn で公開された記事数の約8.9倍という結果でした。
…と、ここで思い浮かぶのは、「カレンダーカテゴリー別だと違う結果になるのではないか?」という予想です。確認してみることにしましょう。

結果(カレンダーカテゴリー別)

プレゼント

プレゼント.png

ドメイン 記事数 割合
qiita.com 241 85.2%
zenn.dev 7 2.5%
note.com 5 1.8%

Qiita公開 のほうが多い

Qiita主催

Qiita主催.png

ドメイン 記事数 割合
qiita.com 97 82.2%
zenn.dev 2 1.7%

Qiita公開 のほうが多い

プログラミング言語

プログラミング言語.png

ドメイン 記事数 割合
qiita.com 714 57.5%
zenn.dev 151 12.9%

Qiita公開 のほうが多い

ライブラリ・フレームワーク

ライブラリ・フレームワーク.png

ドメイン 記事数 割合
qiita.com 454 55.9%
zenn.dev 90 11.1%
github.com 16 2.0%

Qiita公開 のほうが多い

データベース

データベース.png

ドメイン 記事数 割合
qiita.com 63 40.9%
scrapbox.io 25 16.2%
zenn.dev 13 8.4%

Qiita公開 のほうが多い

Webテクノロジー

Webテクノロジー.png

ドメイン 記事数 割合
qiita.com 166 53.4%
zenn.dev 42 13.5%
note.com 35 11.3%

Qiita公開 のほうが多い

モバイル

モバイル.png

ドメイン 記事数 割合
qiita.com 129 61.7%
zenn.dev 41 19.6%

Qiita公開 のほうが多い

DevOps・インフラ

DevOps・インフラ.png

ドメイン 記事数 割合
qiita.com 248 55.4%
zenn.dev 49 10.9%

Qiita公開 のほうが多い

IoT・ハードウェア

IoT・ハードウェア.png

ドメイン 記事数 割合
qiita.com 332 68.2%
zenn.dev 22 4.5%

Qiita公開 のほうが多い

OS

OS.png

ドメイン 記事数 割合
qiita.com 95 77.2%
github.com 3 2.4%
zenn.dev 1 0.8%

Qiita公開 のほうが多い

エディタ

エディタ.png

ドメイン 記事数 割合
zenn.dev 41 32.3%
qiita.com 33 26.0%
twitter.com 23 18.1%
note.com 8 6.3%

Zenn公開 のほうが多い

学術

学術.png

ドメイン 記事数 割合
qiita.com 178 68.7%
zenn.dev 19 7.3%

Qiita公開 のほうが多い

サービス・アプリケーション

サービス・アプリケーション.png

ドメイン 記事数 割合
qiita.com 890 57.0%
zenn.dev 100 6.4%
note.com 75 4.8%
dev.classmethod.jp 60 3.8%
medium.com 28 1.8%

Qiita公開 のほうが多い

企業・学校・団体

企業・学校・団体.png

ドメイン 記事数 割合
qiita.com 3952 61.5%
note.com 431 7.4%
zenn.dev 234 4.0%
medium.com 85 1.5%

Qiita公開 のほうが多い

その他

その他.png

ドメイン 記事数 割合
qiita.com 528 58.9%
note.com 127 14.2%
zenn.dev 66 7.4%

Qiita公開 のほうが多い

未設定

集計せず

「Zenn で公開」の割合が多いカテゴリーがあった!

なんと「エディタ」カテゴリーでは Qiita で公開された記事数よりも、Zenn で公開された記事数のほうが多いという結果でした。
そもそも「エディタ」カテゴリーでは Twitter での公開も多くあり、かなり分散されているのが印象的でした。

また、今回は「ドメイン」で集計していますので、独自ドメインが設定可能なはてなブログや note など、サービス単位でまとめるとまた違った結果が見えてくる可能性もあります。
さらに「カテゴリー」別ではなくそれぞれのカレンダーごとに見てもおもしろいかもしれません。

今回、データを集計するために得たデータについては GitHub で公開していますので、気になる方はこの記事の続きをお読みください…。

実施方法

Mac・iPad の Swift Playgrounds 4 および Mac の Xcode 13.2 で開発可能な .swiftpm プロジェクトを開発しました。
これにより iOS & iPadOS App、macOS Command Line Tool のいずれでも動作します。行った処理は大まかに以下のとおりです。

  1. Qiita Advent Calendar 2021 に登録されているすべてのカレンダーの各情報を JSON に保存する
    1. カレンダータイトル
    2. カレンダー URL
    3. カレンダー参加者数(参加者数がゼロのカレンダーはここで弾く)
  2. 「1.」の情報を元に、各カレンダーの詳細情報と登録されている記事の各情報を JSON に保存する
    1. カレンダータイトル
    2. カレンダーカテゴリ
    3. カレンダー作成者
    4. カレンダー参加者数
    5. カレンダー URL
    6. カレンダー総 LGTM 数
    7. カレンダー購読者数
    8. 登録されている記事情報
      1. シリーズ(カレンダー1、カレンダー2、…)
      2. n日目
      3. 記事タイトル
      4. 記事 URL
      5. 記事作成者
  3. 「2.」の情報をまとめて JSON として出力する
    1. Qiita Advent Calendar 2021 全体の記事総数
    2. 記事 URL にあるドメインとその数

HTML のパーサーには Kanna を用いました。

ディレクトリ構成

基本的には .swiftpm の中に Swift ファイルを配置し、macOS Command Line Tool で使用するための main.swift のみ外側に持ってきています。macOS Command Line Tool から見える main.swift 以外の Swift ファイルは、.swiftpm の中のディレクトリのシンボリックリンクになっています。

QACPercentageSurvey
├── README.md
├── Package.swift
├── Sources
│   ├── 1-StoreCalendarsData
│   │   └── main.swift
│   ├── 2-StoreArticlesData
│   │   └── main.swift
│   ├── 3-AggregateHostPercentages
│   │   └── main.swift
│   └── AppModule
│       ├── Entities   -> ../../QACPercentageSurvey.swiftpm/Entities
│       ├── Extensions -> ../../QACPercentageSurvey.swiftpm/Extensions
│       └── Utilities  -> ../../QACPercentageSurvey.swiftpm/Utilities
└── QACPercentageSurvey.swiftpm
    ├── Package.swift
    ├── QACPercentageSurveyApp.swift
    ├── Assets.xcassets
    │   ├── AccentColor.colorset
    │   │   └── Contents.json
    │   ├── AppIcon.appiconset
    │   │   ├── Contents.json
    │   │   ├── PlaceholderAppIcon-gift-1024.png
    │   │   ├── PlaceholderAppIcon-gift-60@2x.png
    │   │   ├── PlaceholderAppIcon-gift-60@3x.png
    │   │   ├── PlaceholderAppIcon-gift-76@2x.png
    │   │   └── PlaceholderAppIcon-gift-83.5@2x.png
    │   └── Contents.json
    ├── Entities
    │   ├── AggregateHostPercentagesResult.swift
    │   ├── QACalendar.swift
    │   ├── QACalendarArticle.swift
    │   ├── QACalendarArticlesData.swift
    │   └── QACalendarsData.swift
    ├── Extensions
    │   ├── ActivityIndicatorView.swift
    │   ├── ActivityView.swift
    │   ├── JSONDecoder+Extensions.swift
    │   └── JSONEncoder+Exntensions.swift
    ├── Utilities
    │   ├── FileHelper.swift
    │   ├── MyURLSession.swift
    │   ├── QACHelper.swift
    │   ├── QACHelperFor1-StoreCalendarsData.swift
    │   └── QACHelperFor2-StoreArticlesData.swift
    └── Views
        ├── 1-StoreCalendarsDataView.swift
        ├── 2-StoreArticlesDataView.swift
        └── 3-AggregateHostPercentagesResultView.swift

HTTP リクエストの間隔を60秒空ける

一度に大量のアクセスを行わないようにするため、async な Task.sleep(nanoseconds:) を使って HTTP リクエストの間隔を最低60秒空けるようにしました。
また、残りの待機時間が何秒かを Combine の @Published で伝えるようにしました。

2-StoreArticlesDataView.swift
import SwiftUI

@MainActor
struct StoreArticlesDataView: View {
    @ObservedObject private var session = MyURLSession.shared

    // Text("\(MyURLSession.shared.waitingTime) 秒後に接続します…")
    //     .monospacedDigit()
}
MyURLSession.swift
import Foundation
import Combine

public class MyURLSession: ObservableObject {
    public static var shared = MyURLSession()
    
    // ...
    
    @MainActor @Published private(set) var waitingTime: Int = 0
    @MainActor private func set(waitingTime: Int) {
        self.waitingTime = waitingTime
    }
    
    private var session: URLSession { /* ... */ }
    
    private var previousDate: Date? = nil
    public func data(from url: URL) async throws -> Data {
        // ...
        if let previousDate = previousDate {
            // Qiita API v2 ドキュメント https://qiita.com/api/v2/docs の「利用制限」を参考に、自主的に前回のアクセスから最低 60 秒は間隔を空ける
            let interval = DateInterval(start: previousDate, end: Date())
            let requiredWaitingTime = 60 - Int(interval.duration)
            if requiredWaitingTime > .zero {
                await set(waitingTime: requiredWaitingTime)
                for _ in 0..<requiredWaitingTime {
                    try await Task.sleep(nanoseconds: 1 * 1000 * 1000 * 1000)
                    await set(waitingTime: waitingTime - seconds)
                }
            }
        }
        
        let (data, _) = try await session.data(from: url)
        previousDate = Date()
        return data
    }
}

使用したプログラム・生データ JSON の公開

この記事を執筆するために使用したプログラム一式は GitHub で公開しています。
生データ(JSON)も一緒に置いてありますので、再度スクレイピングする必要がありません。
カレンダーごとの割合を出してみたり、ドメインごとではなくサービスごとに調べた結果の公開、どなたかお待ちしております…。

swift.json
{
  "created_at" : "2021-12-22T13:40:49Z",
  "calendar_meta_data" : {
    "author" : "@treastrain",
    "category" : "プログラミング言語",
    "lgtm" : 171,
    "subscribers" : 74,
    "title" : "Swift Advent Calendar 2021",
    "participants" : 19,
    "unique_name" : "swift",
    "url" : "https://qiita.com/advent-calendar/2021/swift"
  },
  "articles" : [
    {
      "series" : "カレンダー1",
      "title" : "Swift5 全予約語 (106語) の解説",
      "author" : "@ezura",
      "day" : 1,
      "url" : "https://qiita.com/ezura/items/a4e43dfdadedb738be8a"
    },
    {
      "series" : "カレンダー1",
      "title" : "Swiftのプロトコルは何?",
      "author" : "@hironytic",
      "day" : 2,
      "url" : "https://qiita.com/hironytic/items/6a50b7cc6dd1ea332ee2"
    },
32
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?