PythonでRedditウェブスクレイパーを作る方法

スポンサーリンク

Redditには数え切れないほどのコミュニティがあり、延々と続く議論、そして本物の人間同士のつながりがあります。

Reddit には、ニュース速報、スポーツ、テレビファン理論、インターネットで最もかわいい動物の無限のストリームなど、あらゆる興味のためのコミュニティがあります。

PythonのPRAW (Python Reddit API Wrapper) パッケージを使って、この記事ではRedditからデータをスクレイピングする方法を説明します。

PRAWはReddit APIのPythonラッパーで、サブRedditからデータをスクレイピングしたり、ボットを開発したり、その他いろいろなことができるようになります。

このチュートリアルの終わりまでに、subredditからできるだけ多くのPython関連のデータをスクレイピングして、RedditユーザーがPythonについて本当に言っていることにアクセスできるようにすることを試みます。

スポンサーリンク

イントロダクション

スクレイピングとは、その名の通り、インターネット上のページからデータを抽出する技術です。

このガイドを含め、ウェブブラウザを使ってインターネット上で見ることができるものはすべて、ローカルのハードディスクにスクレイピングすることが可能です。

ウェブスクレイピングには数多くの用途があります。

データの取得は、あらゆるデータ分析の最初の段階です。

インターネットは全人類の歴史と知識の巨大な貯蔵庫であり、あなたは望む情報を抽出し、それを好きなように利用する力を持っているのです。

Redditからデータをスクレイピングする技術は様々ありますが、PRAWはそのプロセスを簡素化します。

RedditのAPI要件にすべて準拠し、開発者のコードにおけるスリープコールを不要にします。

スクレイパーをインストールする前に、Redditスクレイパーのための認証を設定する必要があります。

それぞれの手順は以下の通りです。

Reddit Scraper の認証手順


PRAWで作業するには認証が必要です。

これを実現するために、以下のステップを踏みます。

  1. このリンクからRedditの開発者アカウントにアクセスします。
    1. ページを一番下までスクロールして、アプリを開発するための「あなたは開発者ですか」ボタンを見つけます。
    1. 次のステップでは、アプリケーションを構築し、フォームに記入し、アプリを開発します。
  2. これで、スクレイパーに必要なすべての情報を含むページに移動します。
pip install praw

リダイレクトURLには、http://localhost:8080を選択します。

完了したら、アプリの作成ボタンをクリックします。

1
2
3
import praw
import pandas as pd
from praw.models import MoreComments

これで認証フェーズが完了したので、次のステップではRedditスクレイパーの実装に進みます。

スクレイパーの実装

このパートでは、このチュートリアルが目指しているデータを取得するために必要なことをすべて説明します。

まず、必要なモジュールとライブラリをすべてプログラムファイルにインポートすることから始めます。

PRAWのライブラリをインポートする前に、コマンドプロンプトで以下の行を実行してPRAWをインストールする必要があります。

1
2
3
4
5
reddit_authorized = praw.Reddit(client_id=" ",
                                client_secret=" ",
                                user_agent=" ",
                                username=" ",
                                password=" ")

PRAWが正常にインストールされたので、以下のコードでPRAWと他の必要なライブラリをインポートできます。

name_subreddit = input("Enter the name of Sub-reddit : ")

先ほど完了した認証手続きは、すぐにでも役に立ちます。

PRAWを使用してデータを収集する前に、ソフトウェアで認証する必要があります。

これはRedditインスタンスまたはAuthorizedインスタンスを作成することで達成できます。

このガイドでは、Redditのアカウントで任意のアクションを実行できるようにするために、オーソライズドインスタンスを作成します。


インスタンスに必要なのは、クライアント ID、クライアントシークレット、ユーザーエージェント、ユーザー名、そしてパスワードだけです。

以下のコードを見てください (空白の文字列ではなく、キーを記入してください)。

1
2
3
4
subreddit = reddit_authorized.subreddit(name_subreddit)
print("Display Name:", subreddit.display_name)
print("Title:", subreddit.title)
print("Description:", subreddit.description)

私たちは、redditorがプラットフォーム上でPythonについて話していることを見つけることを目的としていますが、万が一、気が変わって他のことについて知りたくなった場合には、ユーザー自身からそのトピックについての意見を取り入れることにしています。

下のコードスニペットを見てください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
posts = subreddit.top("week")
 
posts_dict = {"Title": [],
              "Total Comments": [],
              "Post URL": []}
 
for post in posts:
    posts_dict["Title"].append(post.title)
    posts_dict["Total Comments"].append(post.num_comments)
    posts_dict["Post URL"].append(post.url)
 
top_posts_week = pd.DataFrame(posts_dict)
 
print("Number of posts extracted : ",top_posts_week.shape[0])
top_posts_week.head()

次のコードでは、先ほど生成したインスタンスオブジェクトを使って、subredditにアクセスすることを試みます。

さらに、subreddit に関するいくつかの基本的な情報を提供し、アクセスできるかどうかを確認します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
posts = subreddit.top("month")
 
posts_dict = {"Title": [],
              "Total Comments": [],
              "Post URL": []}
 
for post in posts:
    posts_dict["Title"].append(post.title)
    posts_dict["Total Comments"].append(post.num_comments)
    posts_dict["Post URL"].append(post.url)
 
top_posts_month = pd.DataFrame(posts_dict)
 
print("Number of posts extracted : ",top_posts_month.shape[0])
top_posts_month.head()

これからのコードスニペットで、週、月、年の上位の投稿を抽出して、そのトピックの最上位の投稿が何であるかを理解するようにします。

抽出された投稿オブジェクトに対して、forループを使って、投稿のタイトル、コメント数、投稿のURLを抽出する予定です。

分析を容易にするために、データをデータフレームに変換します。

以下のコードは、トピックに関する今週のトップ投稿を抽出します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
posts = subreddit.top("year")
 
posts_dict = {"Title": [],
              "Total Comments": [],
              "Post URL": []}
 
for post in posts:
    posts_dict["Title"].append(post.title)
    posts_dict["Total Comments"].append(post.num_comments)
    posts_dict["Post URL"].append(post.url)
 
top_posts_year = pd.DataFrame(posts_dict)
 
print("Number of posts extracted : ",top_posts_year.shape[0])
top_posts_year.head()

出力は以下のようになり、100件の投稿のデータを抽出できたことがわかります。

1
2
3
4
5
6
7
8
9
10
11
12
13
url = top_posts_month['Post URL'][0]
submission = reddit_authorized.submission(url=url)
 
post_comments = []
for comment in submission.comments:
    if type(comment) == MoreComments:
        continue
    post_comments.append(comment.body)
 
comments_df = pd.DataFrame(post_comments, columns=['comment'])
 
print("Number of Comments : ",comments_df.shape[0])
comments_df.head()

次のコードでは、そのトピックに関する月の上位投稿を取得します。


変更する必要があるのは、 subreddit.top 関数のパラメータだけです。

001 Scraper Step 1

このコードで抽出された月の上位投稿を見てみましょう。

001 Scraper Step 2

最後に、以下のコードでは、そのトピックに関する年間のトップ投稿を取得します。


ここでも変更する必要があるのは、 subreddit.top 関数のパラメータだけです。

002 Top Weekly Posts Reddit

上記のコードで抽出された年間トップ投稿を見てみましょう。

003 Top Monthly Posts Reddit

最後に、以下のコードを使って、投稿のURLからその投稿のすべてのコメントを抽出してみましょう。

これは、Pythonの投稿に対して人々がどのような反応をしているかを知るのに役立ちます。

毎月公開されているPythonの人気記事の中から、最初の投稿からベストコメントを抽出してみます。

これを実現するためには、prawモジュールのMoreCommentsが必要になります。

004 Top Yearly Posts Reddit

次の画像で、抽出された44件のコメントをすべて見てみましょう。

005 Comments Reddit Output

まとめ

PrawはReddit APIのPythonラッパーで、PythonのわかりやすいインターフェースでReddit APIを利用できるようになります。

このAPIはウェブスクレイピング、ボット作成、その他の目的に使用することができます

この記事では、認証、subredditから最も人気のある週、月、年の投稿を取得すること、および投稿のコメントを抽出することに取り組みました。

この記事を楽しんでいただけたなら、次のチュートリアルもチェックすることをお勧めします。

  1. Python Seleniumの紹介とセットアップ
  2. Seleniumを使ってウェブページからデータを取得する [完全ガイド] 2.
  3. PythonでScrapyを使ってYahoo Financeのデータをスクレイピングする方法
タイトルとURLをコピーしました