GolangでRedditのキーワードを監視するには?

Redditの投稿やコメントで言及されているキーワードを監視することは、ブランド、製品、競合他社を監視したり、特定のトピックについて情報を得たりするのに非常に役立ちます。Goはこのようなソーシャルリスニングアプリケーションに最適な言語です。この記事では、Redditのキーワードを監視する簡単なGoプログラムの書き方を紹介します。

GolangでRedditを監視する

Redditにおけるソーシャルメディアリスニング

Redditのソーシャルリスニングは、個人と組織の両方にとって、様々な目的に対応できる非常に強力なツールです。ソーシャルリスニングが特に重要な理由をいくつか挙げてみよう:

Redditで特定のキーワードを監視するには?

Redditは、プラットフォーム上で行われたすべての新しい投稿やコメントを取得できる無料のAPIエンドポイントをいくつか公開している。これらのエンドポイントはあまりよく文書化されていません。

Redditの直近100件の投稿を取得するには、以下のAPIエンドポイントにGET HTTPリクエストを行う必要がある: https://www.reddit.com/r/all/new/.json?limit=100

Redditの直近100件のコメントを取得するには、以下のAPIエンドポイントにGET HTTPリクエストを行う必要がある: https://www.reddit.com/r/all/comments/.json?limit=100

これらのAPIエンドポイントのレスポンスは、投稿やコメントのリストを含むJSONオブジェクトである。

以下は、posts エンドポイントをリクエストしたときに得られたレスポンスの例です:

curl https://www.reddit.com/r/all/new/.json?limit=100

{
"kind": "Listing",
"data": {
    "after": "t3_1asad4n",
    "dist": 100,
    "modhash": "ne8fi0fr55b56b8a75f8075df95fa2f03951cb5812b0f9660d",
    "geo_filter": "",
    "children": [
        {
            "kind": "t3",
            "data": {
                "approved_at_utc": null,
                "subreddit": "GunAccessoriesForSale",
                "selftext": "Morning gents. I\u2019m looking to snag up your forgotten factory yellow spring for the 509T. I need to source one for a buddy who lost his and I cannot find any available anywhere! \n\nIf one of you have the yellow spring laying around, looking to pay $50 shipped\u2026 \n\nTo my 509t owners, it\u2019s the \u201clight\u201d spring that comes in a plastic bag in the carrying case. \n\nThanks in advance  ",
                "author_fullname": "t2_2ezh71n6",
                "saved": false,
                "mod_reason_title": null,
                "gilded": 0,
                "clicked": false,
                "title": "[WTB] 509T yellow spring",
                "link_flair_richtext": [],
                "subreddit_name_prefixed": "r/GunAccessoriesForSale",
                [...]
                "contest_mode": false,
                "mod_reports": [],
                "author_patreon_flair": false,
                "author_flair_text_color": "dark",
                "permalink": "/r/GunAccessoriesForSale/comments/1asadbj/wtb_509t_yellow_spring/",
                "parent_whitelist_status": null,
                "stickied": false,
                "url": "https://www.reddit.com/r/GunAccessoriesForSale/comments/1asadbj/wtb_509t_yellow_spring/",
                "subreddit_subscribers": 182613,
                "created_utc": 1708094934.0,
                "num_crossposts": 0,
                "media": null,
                "is_video": false
                }
            },
        [...]
        ]
    }
}

ご覧のように、Reddit はオブジェクトの配列を返します。各オブジェクトは、投稿やコメント (リクエストしたエンドポイントによって異なります) で、投稿の内容、投稿の URL、作成日時などの包括的な詳細が含まれています。それらのほとんどは役に立ちませんが、"selftext" は投稿やコメントの内容を含んでいるので、間違いなく最も重要な要素です。

結果は降順で表示されます。同時に100件以上の投稿やコメントをリクエストすることはできませんのでご注意ください。

なぜGoを使ってRedditをリアルタイムで監視するのか?

Goプログラミング言語には、Redditの投稿やコメントをリアルタイムで取得するのに最適な強力な機能がいくつかあります。この目的には他のプログラミング言語も使えますが、特にリアルタイムのデータ処理を扱う場合、Goを使うことには特別な利点があります。Goが優れている理由は以下の通りです:

まず、ゴルーチンとして知られるGoの軽量スレッドは、効率的なマルチタスクと並行処理を可能にします。これは特に、複数のReddit投稿やコメントを同時にフェッチするときに便利です。

第二に、Goの標準ライブラリには包括的で効率的なHTTPクライアントが含まれており、ウェブリクエストのプロセスを簡素化できる。これは、RedditのAPIとやりとりして投稿やコメントを取得するのに不可欠です。GoのHTTPクライアントはコンテキストをサポートしており、リクエストのタイムアウトやキャンセルが可能です。これは、アプリケーションの応答性を維持し、遅延した応答でハングアップしないようにしたいリアルタイムアプリケーションには不可欠です。

最後に、Goはコンパイル言語であるため、Goで書かれたアプリケーションは通常、高速でフットプリントが小さい。これは、大量のデータを迅速に処理する必要があるリアルタイム・アプリケーションにとって有益です。Goのガベージ・コレクタは効率的で、レイテンシを低く保つように設計されており、これはリアルタイムのデータ取得シナリオでパフォーマンスを維持するために重要です。

Redditの投稿に含まれるキーワードを監視するシンプルなGoプログラム

ここでは、Goの投稿でキーワード「kwatch.io」を監視するGoプログラムを作るステップ・バイ・ステップの計画を紹介する:

これが囲碁のコードだ:

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "time"
)

type Post struct {
    Selftext  string `json:"selftext"`
    Title     string `json:"title"`
    Permalink string `json:"permalink"`
}

type Data struct {
    Children []struct {
        Data Post `json:"data"`
    } `json:"children"`
}

type Response struct {
    Data Data `json:"data"`
}

func fetchPosts() {
    resp, err := http.Get("https://www.reddit.com/r/all/new/.json?limit=100")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer resp.Body.Close()

    var r Response
    err = json.NewDecoder(resp.Body).Decode(&r)
    if err != nil {
        fmt.Println(err)
        return
    }

    for _, child := range r.Data.Children {
        if strings.Contains(child.Data.Title, "kwatch.io") || strings.Contains(child.Data.Selftext, "kwatch.io") {
            fmt.Println("Title:", child.Data.Title)
            fmt.Println("Selftext:", child.Data.Selftext)
            fmt.Println("Permalink:", child.Data.Permalink)
            fmt.Println()
        }
    }
}

func main() {
    ticker := time.NewTicker(1 * time.Second)
    for range ticker.C {
        fetchPosts()
    }
}

このプログラムは、Redditから1秒ごとに(非同期に)直近の100件の新しい投稿を取得し、各投稿のタイトル、セルフテキスト、パーマリンクをコンソールに表示します。APIのエンドポイントURLを変更するだけで、Redditのコメントでも同じことができます。

このプログラムをどのように改善できるか、いくつかアイデアを挙げてみよう:

結論

Reddit上の特定のキーワードを監視することは、かなりシンプルなGoプログラムのおかげで可能だ。

しかし、このようなプログラムの制作は難しいかもしれない。なぜなら、Redditはリクエストが多すぎるとブロックしてしまうからです。また、RedditのAPIエンドポイントは同時にたくさんの投稿やコメントを返すので、Goプログラムはこの大量のリクエストをスマートに処理しなければなりません。

このようなシステムの構築や保守をご自身で行いたくない場合は、代わりに弊社のプラットフォームをご利用いただくことをお勧めします: KWatch.ioへの登録はこちらから。

Arthur
開発者 KWatch.io