我试着使用MongoDB和pandas,获取了通过YouTube API获取的輝夜月的视频信息

首先

使用YouTube的API检索结果(视频信息),并将其加载到MongoDB中,然后格式化并写入到CSV文件中,或者使用pandas进行分析。

由于可以根据观看次数或点赞数对YouTube的搜索结果进行排序,
所以在像”我有一个很喜欢的YouTuber,但不知道该看哪个视频!”这样的情况下非常方便。

背景 –

最近,我对于从网上获取信息和数据的”网络爬虫”非常感兴趣。因此,我正在参考《Python网络爬虫与数据采集》这本书进行实践,这次就是其中的一部分。

为什么选择了輝夜月这位虚拟YouTuber的视频呢?
因为我非常喜欢輝夜月呀。她的视频有趣又可爱,真是太棒了。
看着輝夜月以虚拟YouTuber的身份飒爽登场,感受到了新时代的来临。
真是个了不起的时代啊。
最近一直没追到她的视频,正好可以补上。

需要做的事情

    1. 使用YouTube的API来收集搜索结果中的视频信息,并将其保存到MongoDB中

 

    1. 对保存的数据进行整理,写入csv文件

 

    使用pandas读取csv文件并进行数据分析

环境

    • Windows10 64bit

 

    • Python3.5

 

    MongoDB 4.0.2

预先准备

    • pandasが必要なのとJupyter Notebookが便利なので、Anacondaも入れておきましょう。

 

    • YouTubeからAPIでデータを取ってくるために、GoogleでAPIキーの取得と設定も行いましょう。

参考:「YouTube Data APIを触ってみよう【導入編】」

コードを実行する前にMongoDBをインストールし、起動させておく必要があります。

参考:「Windows版MongoDBのインストール・MongoShellを通してCRUDコマンドを打ってみる」

代码

使用YouTube的API从搜索结果中收集视频信息,并保存在MongoDB中。

import sys
from apiclient.discovery import build # pip install google-api-python-client
from pymongo import MongoClient, DESCENDING # pip install pymongo

YOUTUBE_API_KEY = '<APIキーを記入>'

query = '輝夜月' # 検索キーワード
max_pages=8 # データを収集するページ数
maxResults=50 # 1ページあたりの動画数
# max_pages * maxResults 分の動画の情報を取ってくる。大きすぎる設定だと途中でエラーが出ることも。

def main():
    """
    メイン処理
    """
    mongo_client = MongoClient('localhost', 27017) # MongoDBと接続
    db = mongo_client.kaguya
    collection = db.luna # kaguyaデータベース -> lunaコレクション
    collection.delete_many({}) # 既存の全てのドキュメントを削除しておく

    for items_per_page in search_videos(query, max_pages, maxResults):
        save_to_mongodb(collection, items_per_page)


def search_videos(query, max_pages=10, maxResults=50):
    """
    動画を検索してページ単位でlistをyieldする
    """
    youtube = build('youtube', 'v3', developerKey = YOUTUBE_API_KEY)

    search_request = youtube.search().list(
        part='id',
        q=query,
        type='video',
        maxResults=maxResults,
    )

    i = 0
    while search_request and i < max_pages:
        search_response = search_request.execute() # execute()で実際にHTTPリクエストを送信。APIのレスポンスを取得。
        video_ids = [item['id']['videoId'] for item in search_response['items']]

        videos_response = youtube.videos().list(
            part='snippet,statistics',
            id=','.join(video_ids)
        ).execute()

        yield videos_response['items']

        search_request = youtube.search().list_next(search_request, search_response)
        i += 1


def save_to_mongodb(collection, items):
    """
    MongoDBにアイテムのリストを保存
    """
    for item in items:
        item['_id'] = item['id']

        for key, value in item['statistics'].items():
            item['statistics'][key] = int(value)

    result = collection.insert_many(items) # コレクションに挿入
    print('Inserted {0} documents'.format(len(result.inserted_ids)), file=sys.stderr)


if __name__ == '__main__':
    main()

将保存的数据从MongoDB中提取出来,并进行格式化,然后写入到csv文件中。

如果以CSV格式保存,即使不是工程师的人也能在Excel中进行排序等分析,非常方便。
※如果直接用Excel打开,会出现乱码问题。请按照以下网站提供的步骤打开。
“不转换字符编码打开UTF-8编码的CSV文件在Excel中的方法”

import csv

mongo_client = MongoClient('localhost', 27017)
db = mongo_client.kaguya
collection = db.luna # kaguyaデータベース -> lunaコレクション

# 列名(1行目)を作成
## [タイトル、URL、チャンネル名、公開日、視聴回数、Like数、Dislike数、コメント数(一部不正確?)、favorite数(不明)]
col_name = ['title', 'url', 'channelTitle', 'publishedAt']
statistics_keys = ['viewCount', 'likeCount', 'dislikeCount', 'commentCount', 'favoriteCount']
col_name.extend(statistics_keys)
sort_key = 'statistics.likeCount' # ひとまずLikeが多い順に保存

with open('youtube_result.csv', 'w', newline='', encoding='utf-8') as output_csv:
    csv_writer = csv.writer(output_csv)
    csv_writer.writerow(col_name) # 列名を記入

    # データを整形しつつcsvに書き込んでいく
    for item in collection.find().sort(sort_key, DESCENDING):
        url = 'https://www.youtube.com/watch?v=' + item['_id']
        row_items = [item['snippet']['title'], url, item['snippet']['channelTitle'], item['snippet']['publishedAt']]

        # 値が入っていない部分を埋めるために統計量についてfor文を回す
        for statistics_key in statistics_keys:
            item['statistics'].setdefault(statistics_key, 0)
            row_items.append(item['statistics'][statistics_key]) # 列名と同じ順番になるようにstatistics_keysでfor文を回す

        csv_writer.writerow(row_items)

另外,您还可以利用MongoDB的集合来提取“輝夜月的官方视频”这一内容。

# 輝夜月の公式動画のみ抽出
# 視聴回数順にソートして表示
for item in collection.find({'snippet.channelTitle': 'Kaguya Luna Official'}).sort('statistics.viewCount', DESCENDING):
    print(item['statistics']['viewCount'], item['snippet']['channelTitle'], item['snippet']['title'])

以下是一部分的输出结果:
初期视频的播放次数很多啊。1

3078789 Kaguya Luna Official 【Getting Over It】月ちゃんおこだよ!!!!!おこ
2949664 Kaguya Luna Official 【自己紹介】輝夜 月の特技がスゴイ!!!!
2677585 Kaguya Luna Official 必殺!あいさつきめてみたっス!!!!!!!!!!!!!!!!!!
2469026 Kaguya Luna Official 老化防止対策してないとかマ?!
……

使用pandas库读取csv文件并进行数据分析。

import pandas as pd

# csvファイルを読み込む
df = pd.read_csv('youtube_result.csv')

# 「活発度」列を作る
## 再生数に対してどれだけのコメントが集まっているか
df['活発度'] = df['commentCount'] / df['viewCount']

# 「好感度」列を作る
## 再生数に対してどれだけLikeが集まっているか
df['好感度'] = df['likeCount'] / df['viewCount']

「活跃度」= 「评论数」/「观看次数」
「好感度」= 「点赞数」/「观看次数」
我们制定这样的定义。考虑到观看次数越多,评论和点赞也更容易集中,为了更公平地进行比较,我们将其除以观看次数。

# 好感度順にソート
# オフィシャル動画のみ抽出
# Jupyter Notebook上で実行すると見やすいです
df[df['channelTitle'] == 'Kaguya Luna Official'].sort_values(by=['好感度'], ascending=False)

请试验一下,结果大致如下:
相对较新且播放次数较少的视频,好感度似乎较高。
好感度指标有点棘手呢……。

pic.PNG

通过使用pandas,可以进行各种其他分析。
由于数据保存在MongoDB或csv中,不需要频繁访问YouTube,从而减轻了对对方的负担。

努力之后,会发现很多有趣的事情!

总结起来

使用API可以如此方便地获取信息,这真是令人惊讶啊。

随着虚拟YouTuber在普通社会中的普及,我们希望不要错过这个热潮。
然而,现在是Vtuber的战国时代。我们没有时间观看所有视频。
利用本次所制作的代码,让我们重点关注主要的视频。

请参考

我主要参考了以下几点来编写代码。

    • 『Pythonクローリング&スクレイピング―データ収集・解析のための実践開発ガイド―』技術評論社

『退屈なことはPythonにやらせよう――ノンプログラマーにもできる自動化処理プログラミング』O’Reilly Japan

csvの書き込みで参考にしました。

GitHub
GitHub是一个基于互联网的代码托管平台。

我已经在GitHub上公开了Jupyter Notebook。
https://github.com/kokokocococo555/youtube-api-demo

问题

    • MongoDBを利用する部分でBulkWriteError: batch op errors occurred というエラーが出ることがある(途中まではデータベースに保存されている)

動画が存在しない部分まで検索対象としていると出ることがある
対象数を減らせば問題なく完了することもあれば、それでもなおエラーが出ることも
対策不明。PCを再起動するとエラーが出ないこともある

誰でも使えるくらいの汎用性を持たせたい

今はAnacondaやMongoDB等の環境構築が大変で、そこそこできる人しか使えない

注意

Webスクレイピングでは著作権等で気をつけるべきことがあります。
以下記事を参考に、ルール・マナーを意識しておきましょう。

    • Webスクレイピングの注意事項一覧 – Qiita

 

    Webスクレイピングの法律周りの話をしよう! – Qiita

相关文章【网页爬取和自动化】

基本的なスクレイピング(BeautifulSoup4)

「小説家になろう」をPythonでスクレイピングして本文を保存する(自然言語処理用コーパス作成) – Qiita

APIを利用したスクレイピング・データベースへの保存(MongoDB)・データ分析の一歩(pandas)

YouTubeのAPIで取得した輝夜月さんの動画情報をMongoDBやpandasで触ってみた – Qiita

JavaScriptを用いたサイトのスクレイピング(Selenium, PhantomJS)

JavaScriptでコンテンツが生成されるサイトのスクレイピング【Selenium+PhantomJS】 – Qiita

メール通知(smtplib)・定期的なプログラムの自動実行(タスクスケジューラ)

「小説家になろう」で新しく公開された記事のメール通知を自動化【Python】 – Qiita

自動ログイン(Selenium, ChromeDriver)

QiitaにSeleniumで自動ログインして全投稿を定期的にバックアップ【Python】 – Qiita

我也在那个时候还在看…我记得当时感受到新时代的来临,非常兴奋。
广告
将在 10 秒后关闭
bannerAds