YouTubeの検索結果から動画のURLを抜き取って、シェルに標準出力するPython関数を作ってみました。

そのまま起動すれば検索結果への即時アクセスが可能になり、関数として実行すればURLのリストが返却されます。

プログラムの概要

フローチャート図

フローチャート図

検索ワードの文字列を使って、SeleniumでYouTubeで検索。検索結果の動画のURLを抽出してシェルに表示します。それだけです。

ソースコード

#! /usr/bin/python3
import re,sys,bs4
from selenium import webdriver
from selenium.webdriver import Firefox, FirefoxOptions

#ヘッドレスモードで起動させる。
options = FirefoxOptions()
options.add_argument('-headless')

def search_youtube(search_words):

    search_words = re.sub(" +","+",search_words)
    search_words = re.sub(" +","+",search_words)
    search_url = "https://www.youtube.com/results?search_query=" + search_words

    try:
        browser = webdriver.Firefox(options=options)
        browser.get(search_url)

    except Exception as e:
        print("ERROR_DOWNLOAD:{}".format(e))
    browser.quit()
        return False

    else:
        #SeleniumをBeautifulSoupに渡す
        youtube_search_result_soup = bs4.BeautifulSoup(browser.page_source, "lxml")
        search_result_links = youtube_search_result_soup.select("#title-wrapper > h3 > a")

        links = []
        
        for i in range(len(search_result_links)):
            link = search_result_links[i].get("href")
            if link != None:
                links.append("https://www.youtube.com" + link)
    
    browser.quit()
    return links

if __name__ == "__main__":
    try:
        while True:
            search_words = input("Please insert search word on Youtube.\n")
            print(search_youtube(search_words))

    except KeyboardInterrupt:
        print("\nprogram was ended.\n")
        sys.exit()

このプログラムの解説

このプログラムはSeleniumを使って起動します。事前にFirefoxにウェブドライバーをインストールしていないと動かないのでご注意ください。

それから、BeautifulSoupも使っています。パーサーとしてlxmlを使用しているので、持っていない方はlxmlの部分をhtml.parserに書き換えてください。

このプログラムは連続で検索結果を表示できるようにするため、whileで無限ループしています。終わりたいときは、Ctrl+Cを押して終了してください。

工夫したところ

YouTubeにSeleniumを使ってアクセス

YouTubeは普通にrequestsモジュールを使ってHTMLをダウンロードしても、動画のURLを入手することはできません。(JavaScriptが実行されないから?)

そこで、通常のブラウザと同じようにアクセスできるSeleniumを使用しました。Seleniumを使ってYouTubeのJavaScriptを実行させることで、HTMLを取得して動画のURLを取得します。

関数として実装させる

search_youtube関数は検索ワードとなる文字列変数を受け取って、その検索結果に表示される動画のURLが格納された、リスト型変数を返却します。

外部から呼び出せば、テキストファイルに格納した検索ワードを連続で検索して、一気に動画URLのリストを手に入れることも可能です。

そうして手に入れた動画のURLのリストを、youtube-dlに.....おっと誰か来たようだ。

動作環境

  • Python3がインストールされたUbuntu
  • ウェブドライバーがインストールされたFirefox
  • BeautifulSoup4、Seleniumモジュールがインストール済み

実際に動かしてみる

それでは、実際に動かしてみましょう。まず、普通に起動すると、以下のように検索ワードの入力を促されます。

検索ワードの入力を促される

今回は著作権問題に触れないように、検索ワードは『著作権フリー 動画』としました。

すると、入力からおよそ3秒後、結果が出力されました。

検索結果の動画URLが表示される

後はこの出力されたURLにアクセスすれば、すぐに動画を見ることができます。whileで無限ループしているので、何回でも検索可能です。

メリットとデメリット

メリット

  • 検索結果の動画URLを、一気に入手可能
  • ソースを少し改造すれば、似たような別の動画共有サイトにも応用できる
  • youtube-dlに.....

検索結果の動画URLを、一気に入手可能

シェルにそのまま標準出力されたリンクを、Ctrlを押しながらクリックすることで、そのまま動画のページに飛ぶことができます。

複数の検索ワードをテキストファイルに格納して、一気に検索することも可能です。ちょっと改造してやれば、誰の投稿が検索結果の一位に表示されているのかを知ることができるでしょう。

ソースを少し改造すれば、似たような別の動画共有サイトにも応用できる

改造すれば他の動画サイトにも対応できる

このソースは、YouTubeだけでなく、ニコ動やデイリーモーションなどの動画共有サイトにも応用可能です。

流れは検索ワードをURLにくっつけてアクセス。動画URLの要素を取得して、標準出力しているだけですから。

要素の名前、URLの値などを書き換えれば別の動画共有サイトにも転用できるでしょう。

youtube-dlに.....

うわっ、何する。やめろ。

デメリット

  • NG動画リストなどの機能が用意されていない
  • 挙動がやや遅い

NG動画リストなどの機能が用意されていない

私がこれまで作ってきたウェブスクレイピングプログラムには、一部の内容を非表示にするNG機能が用意されていました。

しかし、今回は関数化による機能の単純化を推進するためにも、あえてNG機能をオミットさせました。

そのため、人によって嫌いな動画が検索結果に表示されることがありますが、あしからず。NG機能は、いずれ別の関数として実装させる予定です。

挙動がやや遅い

Seleniumを使用しているせいか、挙動がやや遅いです。

とはいえ、YouTubeのHTMLから動画のURLを手に入れるためには、どうしてもJavaScriptを実行させなければなりません。

挙動の遅さを感じないようにするには、cronで夜中に実行させるなどの対策が必要になるでしょう。

結論

テキスト画像、そして遂に動画のウェブスクレイピングもできるようになりました。

動画のウェブスクレイピングは、いつかできれば良いなと思っていましたが、まさかたった50行程度のコードで実現できるとは夢にも思っていませんでした。

これがcronで動かせるようになれば、ますます情報収集が捗るでしょう。

関連記事

Seleniumを使って画像をダウンロードする関数

【内部リンク】URL指定後、Seleniumでページ内の画像を全部ダウンロードするPython関数【プロファイル読み込みあり】

こちらは、Seleniumを使った画像ダウンロード関数です。ログインが必要なTwitterなどのサイトであっても問題なく動作します。

最近ではJavaScriptを実行させなければ、コンテンツを表示させないサイトが増えてきているので、画像収集を効率的に行いたい場合はこちらを使いましょう。

Seleniumを使ったTwitterの自動化

【内部リンク】Seleniumで動く自動ツイートプログラム(ボット)をcronに対応させてみた【連投防止機能付き】

Seleniumは元々、ウェブの自動化ツールです。だから、こんなことも簡単にできます。放っておいても勝手に動いてくれるので、とても快適です。