ビジネスとアカデミックの狭間

スマブラ好きなデータサイエンティストの備忘録

【Python】Selenium+BeautifulSoupを用いたYoutubeチャンネル動画の全取得【スクレイピング】

はじめに

今回は、特定のYouTubeチャンネルの全動画タイトルとURLを取得するケースを想定した、スクレイピング技術を紹介する。Seleniumを利用することで、ページスクロール読み込みが必要となる場合の、スクレイピングが可能になる

事前準備

動作環境

Seleniumによるブラウザ操作を行うため、ChromeのWebDriverをあらかじめ用意しておく必要がある。

$ brew install chromedriver

Pythonライブラリ

以下を実行

$ pip install pandas beautifulsoup4 selenium

スクレイピング処理の全体像

  • 対象のサイトへのリクエス
  • 動的コンテンツ読み込みのためのブラウザ操作
  • レスポンスのパース処理
  • CSVファイルへ保存

コード

import os
from time import sleep
import pandas as pd
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys



class YoutubeChannelVideoScraper(object):

    def __init__(self, user_name, csv_file_name):
        self.youtube_url = "https://www.youtube.com"
        self.user_name = user_name
        self.csv_file_name = csv_file_name
        self.csv_file_path = os.path.join(os.getcwd(), self.csv_file_name+'.csv')
        self.channel_videos_url = os.path.join(self.youtube_url, 'user', self.user_name, 'videos')
        self.titles = []
        self.video_urls = []

    def run(self):
        #ソースの取得
        self.get_page_source()
        #動画とURLの抽出
        self.parse_video_title_and_url()
        #データの保存
        self.save_as_csv_file()

    def get_page_source(self):
        '''
        YoutubeChannelページの
        最下部までスクロールしたページソースを取得
        '''
        # ブラウザ操作の準備
        self.driver = webdriver.Chrome()
        self.driver.get(self.channel_videos_url)
        self.current_html = self.driver.page_source

        # 動画一覧要素へ移動
        element = self.driver.find_element_by_xpath('//*[@class="style-scope ytd-page-manager"]')
        actions = ActionChains(self.driver)
        actions.move_to_element(element)
        actions.perform()
        actions.reset_actions()

        # 最下部までスクロールしたソースを取得
        while True:
            for j in range(100):
                actions.send_keys(Keys.PAGE_DOWN)
            actions.perform()
            sleep(3)
            html = self.driver.page_source
            if self.current_html != html:
                self.current_html=html
            else:
                break

    def parse_video_title_and_url(self):
        '''
        タイトルと動画URLを抽出
        '''
        soup = BeautifulSoup(self.current_html, 'html.parser')
        for i in soup.find_all("a"):
            title = (i.get("title"))
            url = (i.get("href"))
            if title is None:
                continue
            elif url is None:
                continue
            if "/watch?v=" in url:
                self.titles.append(title)
                self.video_urls.append(url)

    def save_as_csv_file(self):
        '''
        CSVファイルとして保存
        '''
        data = {
         "title": self.titles,
         "url": self.video_urls
        }
        pd.DataFrame(data).to_csv(self.csv_file_path,index=False)


if __name__ == "__main__":
    scraper = YoutubeChannelVideoScraper(user_name="HikakinTV", csv_file_name="HikakinTV")
    scraper.run()

実験

実際に作ったコードが動くか確かめる。今回はHikakinTVを対象に、ヒカキンさんが出した過去2600件の動画のタイトルとURLを取得する。スクレイピングしたい対象チャンネル動画のURLに、user_nameが書いてある。そのため、別のチャンネル動画をスクレイピングしたい際は、以下の場所を確認すること。



f:id:ai_study:20190710194640j:plain
Objectの第一引数に入力する user_name が書いてある場所

結果

HikakinTVの動画のタイトルと、URLのパラメータを抽出することができた。

title url
ヒカキン祭りに突撃してウマいもん食べまくるwww /watch?v=qJ2kz2GuMLQ
【世界に50台】シュプリームドラムでドラムデビューしたら爆音すぎw【Supreme Drum】 /watch?v=g3aObIPi0gU
【11億円!?】世界最強のぬいぐるみを購入しました…【DIOR × KAWS /watch?v=VGbMRZM5bfo
シュプリームのお金撃てる銃で札束撃ちまくってみたw【Supreme Cash Canon /watch?v=nU3CSnOUQpo
【感動】ハモネプ2019にヒカキン出ます!【8年ぶり】 /watch?v=cP84Fhr2sH0
巨大猫用ランニングマシン購入!まるお&もふこが突っ走る!? /watch?v=2yUCIU1qvPw
ハゲて悩みすぎて病院に行った話 & その時の写真と動画を公開w /watch?v=5Y1D4SRdxy8
【大雨】YouTuber 4×100mリレーで真剣勝負!【土砂降り】 /watch?v=Yo7iD3HPERU
まるお&もふこのハンパない運動神経をお見せします! /watch?v=utuDcOaPRi0
... ...
My HomeTown - 僕の田舎 /watch?v=61N4TnZBRss
森永 - ICE BOX 巨峰 /watch?v=BGlLyjcVTug
ロイヤルミルクティー 7&i Premium /watch?v=j22QgV8x6eY
リプトン - ダブルリーフミルクティー /watch?v=DaZb9X825b0
Very Cute Cat - お気に入りの猫 - /watch?v=xKZ0zk980k8
ミニストップのバニラソフトクリーム /watch?v=fuW8crzKsaw
MEGMILK - 濃厚とろける杏仁豆腐 /watch?v=0RMK1Za2KVI
期間限定!森永アロエヨーグルト『マンゴー』 /watch?v=dq3XhL7axlc
世界一おいしい飲み物『ピルクル』 - The World Best Juice『Pirukuru』 - /watch?v=0t8CH5BAgLY
Hikakin's Video Blog Channel Open!!! /watch?v=oWwIX_s_aVw

まとめ

今回は、動的ページ読み込みに対応したスクレイピング処理を、SeleniumとBeautifulSoup用いて行った。WebDriverにPhantomJSを利用した記事がいくつかあったが、現在Seleniumでのサポートがされていないことから、Chromedriverを利用したほうがいいと判断した。なお、このようなデータをどのように料理するか?といった記事については、別途書いていきたいと思う。