使用 Python 抓取 YouTube 数据

网络抓取是数据科学家或爱好者获取数据负载的最流行和最有价值的过程之一。在学习或试验数据时,您需要大量数据才能得出结论。网络抓取让我们可以从网站、社交媒体平台、电子商务和其他应用程序获取数据。

通过网络抓取,我们可以从上述应用程序中获取数据进行分析、个人项目等。在从网站抓取数据时,我们必须注意道德限制;您抓取的数据及其用途不得影响或损害来源。网络抓取是一种在不被滥用的情况下导入数据的有效工具。

有些网站允许网页抓取,有些则出于明显的原因不允许!当黑客或侵入者掌握网站上的数据时,这些数据可能会被滥用。抓取网站数据时,请确保该网站允许抓取。

YouTube 是继 Google 之后最常用的应用程序之一。我们都知道我们每天花多少时间在 YouTube 上。YouTube 有一个精心策划的主页,几乎可以满足所有人的需求。它用于教育目的、娱乐、旅行等。

您是否想过是否可以分析您最喜爱的 YouTube 频道的统计数据?如果您可以直观地看到频道的观看次数和视频的受欢迎程度怎么办?使用 Python 可以实现这一点。但如果你可以抓取 YouTube 数据呢?

我们稍后就会这样做。因此,如果您是来这里参加下一个大数据科学项目或作为初学者,请坚持到底,您将拥有一个很棒的项目!但是,如果您要批量抓取数据,YouTube 很有可能会屏蔽您的 IP,您可以使用Bright Data Scraping Browser来批量抓取 YouTube 数据。

本文重点关注三个主题 – 使用 Python 抓取 YouTube 数据、对其进行分析和可视化、

谷歌开发者控制台

首先,您需要有一个 Google 帐户才能执行此步骤。因此,如果您还没有 Google 帐户,请创建一个并继续。

Google开发者控制台是Google Cloud控制台的一部分,它允许开发者管理Google资源,还为Google地图、YouTube和其他第三方应用程序提供API。为什么我们现在需要这个控制台?我们正在从 YouTube 上抓取数据。为此,我们需要启用某些权限并获取用于抓取数据的密钥。

让我们看看如何获​​得密钥。

在浏览器中,搜索Google 开发者控制台并单击第一个链接。您可能会看到一个显示条款和条件的弹出窗口。选中该框并单击AGREE AND CONTINUE您需要在控制台中创建一个项目。参考下图创建项目。

创建第一个项目

创建项目可能需要一些时间。完成后,单击您的项目并导航至Credentials左侧的 API 和服务下方,如下所示。

证书

选择 API 密钥并复制“+创建凭据”下生成的密钥。

API密钥

将密钥保存在某处,因为我们在后续步骤中需要它。

您还需要为 Youtube 数据 API 启用 API 服务。

为此,您需要导航到库部分,

导航至 API 库
选择 Youtube Data Api V3
启用API

第一步完成了!

YouTube API

Youtube API 是有助于将 youtube 集成到我们的项目环境中的官方文档。本文档包含我们将要执行的抓取的所有资源和代码片段。

youtube API 具有每个活动的代码示例,可以在我们的环境中进行测试。代码示例是用多种语言编写的,我们可以根据自己的喜好选择任何语言。

那么让我们开始吧!

在浏览器中搜索Youtube API并单击第一个链接。在开始使用资源之前,让我们检查一下使用 API 需要满足的要求。

您可以按照以下导航步骤找到 Python 的要求。

Add Youtube functionality to your site>> Quickstarts_Python

根据 API,它仅与 Python 版本兼容 – 2.7 或 3.5 及更高版本。

我们在第一步中生成的 API 密钥也有一些限制。让我们来看看它们。

API 密钥的限制

我们之前生成的密钥的默认分配量为每天 10,000 个单位。所以用完后当天就不能再使用了。让我们看一下一些常见的操作及其使用成本。

读取操作(检索频道、视频和播放列表数据)通常花费 1 个单位。

写入操作 – 创建、更新或删除数据中的资源可能会花费 50 个单位。

典型的搜索操作最多可能需要 100 个单元。

一个视频上传费用为1600个单位。

明亮的数据抓取浏览器

由于YouTube API限制不适合企业,我们推​​荐Bright Data的Scraping Browser它是一个强大的工具,专为抓取网络数据而设计。该浏览器可以轻松访问目标网站,并允许您与其 HTML 代码交互以提取相关数据。与其他自动化浏览器不同,Scraping Browser 是唯一具有内置网站解锁功能的浏览器,包括验证码解决、浏览器指纹识别和自动重试。这意味着您可以节省时间和资源,同时绕过最困难的网站阻止并智胜任何机器人检测软件。

此外,Scraping Browser 与 Puppeteer 和 Playwright API 兼容,从而可以无缝迁移和使用远程浏览器。您可以轻松获取任意数量的浏览器会话,与它们交互,并从需要交互的网站检索数据。借助 Scraping Browser,您可以根据需要使用任意数量的浏览器来扩展数据抓取项目,而无需担心内部开发和维护复杂的基础设施。

抓取 YouTube 数据

在开始之前,我们需要从 youtube API 文档安装两个包。

安装软件包

我们需要安装红色标记的两个包。上述命令适用于虚拟环境,但如果您使用 Colab 或 Jupyter 或 JupyterLab 等笔记本,则需要使用以下命令。

pip3 install --upgrade google-api-python-client
pip3 install --upgrade google-auth-oauthlib google-auth-httplib2

第一个命令是用于启用 API 服务的 API 客户端,第二个命令用于授权 youtube 用户/所有者。

还记得您在第一步中保存的 API 密钥吗?将该密钥复制到笔记本的一个单元格中。

让我们安装并导入所有必要的库以进行抓取、分析和可视化。

1
2
3
4
5
6
7
8
9
10
11
12
from googleapiclient.discovery import build
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
!pip3 install isodate
!pip3 install wordcloud
from wordcloud import WordCloud
from nltk.corpus import stopwords
import nltk
nltk.download('stopwords')

代码的第一行用于创建一个 API 客户端,允许用户与 Google 的服务进行交互。我们将使用它来构建一个客户端,获取 API 密钥并让我们使用 Youtube 的服务。

Pandas 库用于根据我们抓取的数据创建数据框。Seaborn 和 Matplotlib 用于数据可视化。

接下来的两个包用于支持我们使用的凭据,

Isodate 用于将 Youtube API 的日期格式转换为我们可以理解的格式。

最后利用wordcloud模块将文字精美的展示出来。nltk库的停用词用于从数据中删除停用词。

抓取频道统计数据

在继续抓取之前,我们需要构建一个 API 客户端。按照下面的代码构建客户端。

youtube = build('youtube', 'v3', developerKey=apikey)

这里,youtube 是 API 的名称,v3 是版本。apikey是分配给之前生成的密钥的变量。

我们要从中抓取数据的渠道是freecodecamp.org许多学生和开发人员信任的流行渠道。

我们将把这个通道的 ID 存储在一个名为 的变量中cids频道ID可以通过访问youtube频道并复制地址栏中的URL来获取。如果您愿意,可以使用任何其他渠道。

cids=['UC8butISFwT-Wl7EV0hUK0BQ']

现在我们不需要编写任何代码来抓取数据。API 中给出了所有示例,我们将修改它们以适合我们的用例。

在 Youtube API 中,导航到主页上的“搜索内容”选项卡。您需要导航到频道列表,如下所示。

频道号

在用例表中,单击 旁边的符号list(by Channel ID)您将登陆一个代码页。选择 Python 作为语言。

ChannelID 代码

我们使用的代码如下所示。

频道ID码

我们将稍微修改此代码并创建一个函数来抓取数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 号
18
def chstats(youtube,cids):
     request = youtube.channels().list(
        part="snippet,contentDetails,statistics",
        id=','.join(cids))
    response = request.execute()
    channels_data = []
    for item in response['items']:
        data={
            'ChannelName': item['snippet']['title'],
            'Subscribers': item['statistics']['subscriberCount'],
            'Views': item['statistics']['viewCount'],
            'TotalViews': item['statistics']['videoCount'],
            'PlaylistID': item['contentDetails']['relatedPlaylists']['uploads']
        }
        channels_data.append(data)
    df=pd.DataFrame(channels_data)
    return df
chstats(youtube, cids)

首先,我们定义一个名为 chstats 的函数,用于获取所有通道数据。我们正在创建一个名为的空列表channels_data来存储所有详细信息。响应对象获取我们想要的所有数据。我们需要的数据存储在一个称为 data 的字典中。我们正在获取频道名称、订阅者数量、频道观看次数和播放列表 ID。

该字典被附加到我们创建的空列表中。然后使用字典来渲染数据框,因为这就是我们从一开始就计划做的事情。

了解如何从字典创建数据框。

然后调用该函数来打印数据帧。

相关:如何返回重塑的数据框?

抓取频道统计数据

就像这样,我们就有了一个存储所有渠道详细信息的数据框。

我们将利用PlaylistID上一步获得的数据进行深入分析。

抓取频道的播放列表 ID

我们可以获取频道上每个视频的ID。就像上面的例子一样,导航到 来PlaylistItems获取代码。

播放列表ID代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 号
# Define the playlist ID for the channel
PlaylistID = "UU8butISFwT-Wl7EV0hUK0BQ"
# Define a function to retrieve the video IDs for a given playlist
def vdids(youtube, playlist_id):
    videoids = []
    request = youtube.playlistItems().list(
        part="snippet,contentDetails",
        playlistId=playlist_id,
        maxResults=50)
    response = request.execute()
    for item in response['items']:
        videoids.append(item['contentDetails']['videoId'])
    return videoids
 
# Call the vdids function to retrieve the video IDs for the given playlist
video_ids = vdids(youtube, PlaylistID)
print(video_ids)

在此代码中,我们尝试获取频道配置文件中前 50 个视频的 IDS。maxResults的最大值是50。如果我们想要更多的ID,我们需要使用其他方法。

抓取 VideoID

上述步骤中获得的视频 ID 创建所有所需视频细节的数据帧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 号
18
19
20
21
22 号
23
24
def getvid_details(youtube,video_ids):
    all_info=[]
    for i in range(0,len(video_ids),50):
        request = youtube.videos().list(
            part="snippet,contentDetails,statistics",
            id=','.join(video_ids[i:i+50])
    )
    response = request.execute()
    for video in response['items']:
        keepstats={'snippet':['channelTitle','title','description','tags','publishedAt'],
               'statistics':['viewCount','likeCount','favouriteCount','commentCount'],
               'contentDetails':['duration','definition','caption']
              }
        video_info={}
        video_info['video_id']=video['id']
        for k in keepstats.keys():
            for v in keepstats[k]:
                try:
                    video_info[v]=video[k][v]
                except:
                    video_info[v]=None
                 
        all_info.append(video_info)
    return (pd.DataFrame(all_info))

用于getvid_details获取有关视频的详细信息,例如视频标题、提供的描述、标签、各种计数和持续时间。

我们正在创建一个名为的空字典video_info来存储详细信息。有些视频可能没有提供标签。为了避免遇到错误,我们使用了 try- except 块。

然后将字典转换为数据框。

vdf=getvid_details(youtube,video_ids)
vdf.head()

该数据帧称为vdf。我们使用该函数打印数据帧的前 5 个条目head

数据框

这就是我们如何在 Python 的帮助下抓取 YouTube 数据。现在我们有了最终的数据框,让我们执行一些数据预处理并将其可视化。

数据预处理

让我们获取数据框并对其进行分析。

vdf.isnull().any()

isnull()函数用于检查数据框中的任何对象是否具有空值。

检查数据帧是否包含空值

从输出中可以看到,字段 tag 和 favouriteCount 具有空值。您现在可以放弃它们或忽略它们。

让我们检查数据框中字段的数据类型。

vdf.dtypes
对象的数据类型

正如您所看到的,字段的数据类型 – viewCount、likeCount 和 commentCount 都是对象。但它们应该是数字,你不觉得吗?

让我们更改这些字段的数据类型。

num_cols=['viewCount','likeCount','favouriteCount','commentCount']
vdf[num_cols]=vdf[num_cols].apply(pd.to_numeric,errors='coerce',axis=1)

此代码片段会将字段的数据类型从对象转换为数字。

如果您查看duration数据帧 vdf 的字段,您会发现它采用字母数字格式。但我们需要时间格式。让我们也改变这个领域。

import isodate
vdf['durationSec'] = vdf['duration'].apply(lambda x: isodate.parse_duration(x))
vdf[['duration','durationSec']]

输出如下所示。

持续时间(以小时为单位)

预处理步骤到此结束。您甚至可以添加一些其他步骤并对其进行分析。

可视化抓取的数据

让我们从一个简单的可视化开始。让我们绘制观看次数与点赞数的关系图,以检查人们是否观看了视频或只是点赞并离开。如果关系是线性的,我们可以说观看该视频的每个人也喜欢该视频。

1
2
3
4
5
6
7
sample_df = vdf.sample(n=25, random_state=42,replace=True)
plt.scatter(sample_df['viewCount'], sample_df['likeCount'])
plt.xticks(rotation=90)
plt.xlabel('Views')
plt.ylabel('Likes')
plt.title('Views vs Likes')
plt.show()

我们采用了一个示例数据框,因为原始数据框有 50 行,并且绘制 50 个条目会变得混乱,因为值可能重叠。x 标签的旋转是为了避免值相互重叠。

观看次数与喜欢次数

现在让我们按标题检查视频的受欢迎程度。

ax=sns.barplot(x='viewCount',y='title',data=vdf.sort_values('viewCount',ascending=False)[0:11])
plot=ax.set_xticklabels(ax.get_xticklabels(),rotation=360)

在此代码中,我们通过标题检查视频的受欢迎程度。我们正在检查前 12 个视频的受欢迎程度。标题通常指定一个 x 轴。由于标题很大并且很难在一帧中获得输出,因此我们切换了轴。

视频的受欢迎程度(从高到低)

可以看到,名为《初学者基础教程》的视频获得了第一名!

现在,让我们看看频道标题中最常用的单词freecodecamp并生成词云。

了解如何使用 Python 创建词云。

我们使用 nltk 库生成单词的词云。

1
2
3
4
5
6
7
8
9
10
stop_words=set(stopwords.words('english'))
vdf['title_no_stopwords']=vdf['title'].apply(lambda x:[item for item in str(x).split() if item not in stop_words])
all_words= list([a for b in vdf['title_no_stopwords'].tolist() for a in b])
all_words_str=','.join(all_words)
def plotcloud(wordcloud):
    plt.figure(figsize=(30,20))
    plt.imshow(wordcloud)
    plt.axis("off");
wordcloud=WordCloud(width=2000,height=1000,random_state=1,background_color='gray',colormap='magma',collocations=False).generate(all_words_str)
plotcloud(wordcloud)

首先,我们从标题中删除停用词。我们经常使用停用词来表示“the”、“it”、“a”、“so”、“what”等。

接下来,我们创建一个函数来绘制背景颜色为灰色的词云,并指定云的尺寸。

词云

当然!freecodecamp都是关于教程的。所以Tutorial这个词占据了大部分的云空间。下一个经常使用的词是课程。

结论

我们已经到了本文的结尾。概括地说,我们已经简要讨论了网络抓取以及网络抓取如何成为以合乎道德的方式获取大量数据的有用工具。我们必须谨慎对待我们选择的网站和我们抓取的数据。我们不惜一切代价执行的抓取不应影响数据所有者。

我们经常发现自己沉迷于 YouTube 并滚动浏览视频。我们可以使用抓取从 youtube 获取数据。借助 Google 开发者控制台生成的开发者密钥和 Youtube API 中提供的代码示例,可以实现这一点。

Youtube API 是一个专用文档,允许我们将 YouTube 数据合并到我们的项目中。

我们可以使用 API 文档中的代码片段来抓取数据。在抓取数据时,我们尝试获取频道的基本详细信息,例如订阅者数量、频道名称等。我们使用这些数据作为垫脚石进行更深入的挖掘。

我们根据抓取的数据创建了一个数据框并进行了一些预处理。我们检查了数据框中的字段是否有空值以及字段的数据类型,并对现有数据类型进行了一些更改。

在可视化方面,我们绘制了频道示例视频的观看次数和点赞次数的散点图。

然后,我们根据视频的标题检查了视频的受欢迎程度。最后,我们创建了一个令人惊叹的词云,其中包含频道标题中最常用的词。

当然,您可以对数据进行更深入的分析。您甚至可以使用我们获得的开发者密钥来执行基于特定关键字的搜索任务。这样做时要小心,不要用完你的钥匙!祝你编码愉快!

参考

您可以在此处找到使用的频道页面。

可以在此处找到 Youtube API 文档。

明亮的数据抓取浏览器