用 Python 构建 Reddit 网络爬虫

Reddit 是无数社区、无休无止的讨论和真正的人际关系的家园。Reddit 拥有适合各种兴趣的社区,包括突发新闻、体育、电视迷理论以及源源不断的互联网上最漂亮的动物。

本教程将使用 Python 的 PRAW(Python Reddit API Wrapper)包演示如何从 Reddit 中抓取数据。PRAW 是 Reddit API 的 Python 包装器,允许您从 Reddit 子版块中抓取数据、开发机器人等等。

在本教程结束时,我们将尝试从 Reddit 子版块中抓取尽可能多的 Python 相关数据,并了解 Reddit 用户对 Python 的真实评价。让我们开始享受乐趣吧!


介绍

顾名思义,它是一种从在线页面“抓取”或提取数据的技术。使用网络浏览器可以在互联网上看到的所有内容(包括本指南)都可以复制到本地硬盘上。网络抓取有许多应用程序。数据捕获是任何数据分析的第一阶段。互联网是所有人类历史和知识的巨大存储库,您有能力提取您想要的任何信息并按照您认为合适的方式使用它。

尽管有多种技术可以从 Reddit 上抓取数据,但 PRAW 简化了该过程。它遵守所有 Reddit API 要求,并消除了开发人员代码中睡眠调用的需要。在安装抓取工具之前,必须设置 Reddit 抓取工具的身份验证。下面列出了各个步骤。


Reddit Scraper 的身份验证步骤

使用 PRAW 需要身份验证。为了实现这一目标,我们将采取以下步骤:

  1. 点击此链接访问 Reddit 开发者帐户。
  2. 滚动到页面底部找到“你是开发人员吗?” 按钮来开发应用程序。
  3. 下一步是构建应用程序、填写表单并开发应用程序。
  4. 这将带您进入包含抓取工具所需的所有信息的页面。
001 刮刀 步骤 1

对于重定向 URL,您应该选择 http://localhost:8080完成后,单击创建应用程序按钮。

001 刮刀步骤2

现在身份验证阶段已经完成,我们将在下一步中继续实施 Reddit scraper。


刮刀的实施

本部分将解释为获取本教程旨在获取的数据而必须执行的所有操作。我们首先将所有必需的模块和库导入到程序文件中。在导入 PRAW 库之前,我们必须通过在命令提示符下执行以下行来安装 PRAW:

pip install praw

现在 PRAW 已成功安装,可以使用以下代码片段将 PRAW 与其他所需的库一起导入。

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

我们刚刚完成的身份验证过程将立即有用。在使用 PRAW 抓取任何数据之前,我们必须在软件中进行身份验证。这可以通过创建 Reddit 实例或授权实例来完成。

在本指南中,我们将创建一个授权实例,允许我们使用 Reddit 帐户执行我们想要的任何操作。您只需向实例提供客户端 ID、客户端密码、用户代理、用户名和密码。检查下面的代码片段(填写您的键而不是空白字符串)。

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

我们的目标是在平台上找到 Reddit 用户谈论 Python 的内容,但如果您改变主意并想了解其他内容,我们将从用户本身获取有关该主题的输入。看下面的代码片段。

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

使用下面的代码,我们接下来将尝试使用我们之前生成的实例对象来访问 subreddit。此外,我们将提供一些有关 Reddit 子版块的基本信息,以检查我们是否有权访问。

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

我们将尝试在接下来的代码片段中提取每周、每月和每年最热门的帖子,以了解该主题的最热门帖子是什么。我们将借助提取的帖子对象上的 for 循环来提取帖子的标题、评论数和帖子的 URL。

为了使分析更容易,我们将数据转换为数据框。下面的代码将提取本周有关该主题的热门帖子。

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()

输出看起来有点像下面所示,您可以看到我们能够提取 100 个帖子的数据。

002 Reddit 每周热门帖子

下一个代码片段将获得本月有关该主题的热门帖子。您需要更改的只是函数的参数subreddit.top

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()

查看通过代码提取的每月热门帖子。

003 Reddit 每月热门帖子

最后,以下代码片段将获得该主题的年度热门帖子。同样,您需要更改的只是函数的参数subreddit.top

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()

查看通过上面的代码提取的年度热门帖子。

004 Reddit 年度热门帖子

最后,我们还尝试使用下面的代码片段借助帖子 URL 来提取帖子的所有评论。这将有助于了解人们对 Python 帖子的反应。

我们将从每月发布的最流行的 Python 文章的初始帖子中提取最佳评论。要实现此目的,需要 praw 模块下的 MoreComments。

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()

请查看下图中为该帖子提取的所有 44 条评论。

005 条评论 Reddit 输出

结论

Praw 是 Reddit API 的 Python 包装器,允许我们通过简单的 Python 接口使用 Reddit API。该 API 可用于网络抓取、机器人创建和其他目的。本教程解决了身份验证问题,从 Reddit 子版块中检索最受欢迎的每周、每月和每年的帖子,以及提取帖子的评论。

我希望您喜欢这篇文章,如果您喜欢,我建议您还查看以下教程:

  1. Python Selenium 简介和设置
  2. 使用 Selenium 从网页获取数据 [完整指南]
  3. 如何使用 Scrapy 在 Python 中抓取雅虎财经数据