requestsとBeautifulSoupで作るTikTok動画ダウンローダープロジェクト

目次

プロジェクト概要

前提条件

  • Pythonプログラミングの基本的な知識(変数、関数、クラスの概念)
  • VSCodeエディタの基本操作ができること
  • ターミナル(コマンドライン)の基本的な使用経験
  • Gitとバージョン管理の基礎知識
  • HTMLの基本構造に関する理解

開発環境

  • Python 3.7以上
  • VSCode(Visual Studio Code)
  • Git(バージョン管理システム)
  • GitHubアカウント
  • requests
  • beautifulsoup4

プロジェクト内容

このプロジェクトでは、PythonのrequestsライブラリとBeautifulSoupを使用して、TikTokの動画URLから動画ファイルを自動的にダウンロードするシステムを構築します。初心者でも段階的に学習できるよう、基本的な環境設定から実用的なダウンロード機能まで、5つのステップに分けて実装していきます。

プロジェクトの核となるのは、HTTP通信を使用したWebスクレイピング技術です。requestsライブラリでAPIとの通信を行い、BeautifulSoupでHTML解析を実行することで、動画の直接ダウンロードリンクを抽出します。これにより、実際の業務で活用できる実用的なツールを作成できます。

データ抽出においては、BeautifulSoupの強力なHTML解析機能を使用して、Webページから特定の要素を正確に取得します。単純なデータ収集にとどまらず、取得したデータの検証やエラーハンドリングも実装し、安定性の高いシステムを構築します。

プロジェクトの特徴として、オブジェクト指向プログラミングを採用したクラス設計を行います。TikTokDownloaderクラスを中心とした構造化されたコード設計により、各機能を独立したメソッドとして実装し、コードの可読性と保守性を向上させます。

また、ユーザーフレンドリーな対話式インターフェースも実装し、複数の動画を連続してダウンロードできる機能を提供します。これにより、単なるスクリプトではなく、実際に活用できるアプリケーションとして完成させます。

開発プロセスでは、エラーハンドリングを重視した設計を採用します。ネットワークエラー、ファイル操作エラー、API応答エラーなど、様々な例外状況に対応できるよう、適切なtry-except文を配置し、ユーザーに分かりやすいエラーメッセージを提供します。

実装内容

  • HTTP通信用ヘッダーの設定とAPI連携システム
  • 仮想環境の構築と依存関係管理(requirements.txt)
  • BeautifulSoupを使用したHTML解析とリンク抽出
  • URL検証機能とファイル名自動生成システム
  • 動画ファイルダウンロードとローカル保存機能
  • 対話式ユーザーインターフェースの実装
  • エラーハンドリングと例外処理システム
  • GitHubでのバージョン管理とポートフォリオ公開

得られるスキル

  • requestsライブラリを使用したHTTP通信技術
  • BeautifulSoupを使用したHTML解析とWebスクレイピング
  • オブジェクト指向プログラミング(クラス設計と実装)
  • エラーハンドリング(try-except文の実践的な使用)

得られる経験

  • 実際のAPIとの連携経験
  • Webスクレイピング技術の実践的な習得
  • ファイル操作とディレクトリ管理の実装
  • ユーザーインターフェース設計の基礎

得られる成果物

  • 完全に動作するTikTok動画ダウンローダー
  • GitHubでのポートフォリオとして活用可能なプロジェクト
  • 完全なPythonソースコード

このプロジェクトから応用できること

  • YouTubeダウンローダーツールの開発
  • 画像一括ダウンロードシステムの作成
  • Webサイトの定期監視ツールの構築
  • 商品価格監視システムの開発
  • ニュース記事自動収集ツールの作成

Step1:開発環境の準備とプロジェクト構造の作成

このステップでは、TikTok動画ダウンローダープロジェクトを始めるための開発環境を整備し、必要なファイル構造を作成していきます。プログラミングを始める前の準備段階として、とても重要な作業になります。

※Step1の内容がわからない際は、下記記事にGitHubとVSCodeの連携について詳細を記載しているためご参照ください。

GitHubリポジトリの作成

まず最初に、プロジェクト専用のGitHubリポジトリを作成しましょう。

  1. GitHubの公式サイトにアクセスし、自分のアカウントでログインします
  2. 画面右上の「+」アイコンをクリックし、ドロップダウンメニューから「New repository」を選択します
  3. 新しいリポジトリの作成ページで、以下の情報を入力します

リポジトリの設定

  • Repository nametiktok_downloader」と入力
  • DescriptionTikTok動画ダウンローダーツール」と入力
  • VisibilityPublic」を選択(ポートフォリオとして公開するため)
  • Initialize this repository with
    • Add a README file」にチェックを入れる
    • Add .gitignore」で「Python」を選択
    • Choose a license」は「None」のままにする
  1. Create repository」ボタンをクリックしてリポジトリを作成します

プロジェクトフォルダの作成

次に、プロジェクトを管理するための親フォルダを作成しましょう。

Windows・macOS共通

  1. デスクトップや任意の場所に新しいフォルダを作成します
  2. フォルダ名は任意ですが、ここでは例として「PythonPortfolio」に設定します

この親フォルダが、今後のプロジェクト全体を管理するルートディレクトリとなります。複数のプロジェクトを整理して管理するために作成しておくと便利です。

VSCodeでプロジェクトを開く

作成したGitHubリポジトリをローカルにクローンして開きましょう。

  1. VSCodeを起動します
  2. 左側のアクティビティバーからソース管理アイコン(分岐のようなアイコン)をクリックします
  3. リポジトリの複製」ボタンをクリックします
  4. GitHubから複製」を選択します
  5. 先ほど作成した「tiktok_downloader」リポジトリを選択します
  6. リポジトリ宛先として先ほど作成した親フォルダを選択します
  7. クローンしたリポジトリを開きますか」というウィンドウが表示されたら「開く」をクリックします

VSCodeの左側にエクスプローラーパネルが表示され、現在のプロジェクトフォルダの中身が確認できるようになります。

仮想環境の作成とアクティベート

Python開発において仮想環境は非常に重要です。仮想環境とは、プロジェクトごとに独立したPython実行環境を作成する仕組みのことです。これにより、プロジェクト間でのライブラリの競合を防ぎ、クリーンな開発環境を維持できます。

詳しくは下記記事をご参照ください。

Windows環境での仮想環境作成

  1. VSCodeの上部メニューから「ターミナル」→「新しいターミナル」を選択
  2. 以下のコマンドで仮想環境を作成します
python -m venv myenv
  1. 仮想環境をアクティベートします
myenv\Scripts\activate

macOS環境での仮想環境作成

  1. VSCodeの上部メニューから「ターミナル」→「新しいターミナル」を選択
  2. 以下のコマンドで仮想環境を作成します
python3 -m venv myenv
  1. 仮想環境をアクティベートします
source myenv/bin/activate

重要なポイント

  • 仮想環境名は「myenv」として作成
  • ターミナルの行頭に「(myenv)」と表示されることを確認
  • この表示があることで、仮想環境が正常にアクティベートされていることがわかります

プロジェクトファイル構造の作成

次に、今回のTikTok動画ダウンローダープロジェクトに必要なフォルダとファイルを作成していきます。VSCodeのエクスプローラーパネルを使用してファイルを作成しましょう。

ソースコード用フォルダの作成

  1. VSCodeの左側エクスプローラーパネルで「新しいフォルダ」アイコン(フォルダの絵とプラスのマークがあるアイコン)をクリック
  2. フォルダ名を「src」として作成

この「src」フォルダはsource code(ソースコード)の略で、プログラムのメインファイルを格納するための専用フォルダです。プロジェクトの整理整頓において重要な役割を果たします。

ダウンロード動画用フォルダの作成

  1. 同じくエクスプローラーパネルで「新しいフォルダ」アイコンをクリック
  2. フォルダ名を「downloaded_videos」として作成

downloaded_videos」フォルダは、ダウンロードした動画ファイルを保管するためのフォルダです。今回のプロジェクトでは、TikTokからダウンロードした動画ファイルがここに保存されます。

メインプログラムファイルの作成

  1. 先ほど作成した「src」フォルダをクリックして選択
  2. 新しいファイル」アイコン(ファイルの絵とプラスのマークがあるアイコン)をクリック
  3. ファイル名を「video_downloader.py」として作成

この「video_downloader.py」ファイルが、今回のTikTok動画ダウンロード機能を実装するメインプログラムとなります。.py拡張子Pythonスクリプトファイルであることを示しており、実行可能なプログラムコードを記述するために使用します。

依存関係管理ファイルの作成

  1. プロジェクトのルートフォルダ(tiktok_downloader)をクリックして選択
  2. 新しいファイル」アイコンをクリック
  3. ファイル名を「requirements.txt」として作成

requirements.txtファイルは、Pythonプロジェクトで使用する外部ライブラリとそのバージョンを記録するための重要なファイルです。これにより、他の開発者や本番環境でも同じライブラリ環境を再現できます。

requirements.txtの内容設定

作成した「requirements.txt」ファイルをVSCodeで開き、以下の内容を記述してください。

requests==2.32.3
beautifulsoup4==4.13.4

今回のプロジェクトでは、requestsbeautifulsoup4の2つのライブラリを使用します。

  • requests HTTP通信を簡単に行うためのライブラリです。WebサイトやAPIに対してデータの送受信を行う際に使用します。TikTokの動画情報を取得する際に重要な役割を果たします
  • beautifulsoup4 HTML文書を解析し、必要な情報を抽出するためのライブラリです。Webスクレイピングにおいて、HTMLから特定の要素を取得する際に使用します

プロジェクト構造の確認

この時点で、VSCodeのエクスプローラーパネルには以下のような構造が表示されているはずです。

tiktok_downloader/
├── myenv/                      # 仮想環境フォルダ
├── src/
│   └── video_downloader.py     # メインプログラムファイル
├── downloaded_videos/          # ダウンロード動画保存フォルダ
├── requirements.txt            # 依存関係管理ファイル
├── README.md                   # プロジェクト説明書(GitHub作成時に自動生成)
└── .gitignore                  # Git除外設定ファイル(GitHub作成時に自動生成)

この基本構造が、今回のTikTok動画ダウンローダープロジェクトの基盤となります。GitHubで作成したリポジトリをクローンしたため、README.md.gitignoreファイルが最初から含まれています。

仮想環境が正常にアクティベートされていることを再度確認し(ターミナルに「(myenv)」が表示されている状態)、次のステップに進む準備を整えましょう。

ライブラリのインストール

仮想環境がアクティベートされている状態で、VSCodeのターミナルから以下のコマンドを実行します。

pip install -r requirements.txt

このコマンドにより、requirements.txtに記載されたrequestsとbeautifulsoup4ライブラリがインストールされます。インストール処理には数十秒程度かかる場合がありますので、しばらくお待ちください。

インストールが完了すると、ターミナルに「Successfully installed requests-2.32.3 beautifulsoup4-4.13.4」のようなメッセージが表示され、プロジェクトの環境準備が完了します。

Step2:基本設定ファイル作成とHTTPリクエスト設定

このステップでは、TikTok動画ダウンローダーの基本設定HTTPリクエスト処理のための設定を実装します。Web上のAPIと通信するための必要な設定を整備していきます。

TikTokDownloaderクラスの作成

まず、動画ダウンローダー機能をまとめて管理するクラスを作成します。このクラスの中に、今後必要な機能をすべてdef文(関数)として実装していきます。

src/video_downloader.py」ファイルを開き、以下のコードを記述してください。

# 必要なライブラリをインポート
import os  # ファイルやフォルダの操作に使用
import requests  # HTTP通信(ウェブとのやり取り)に使用
from bs4 import BeautifulSoup  # HTMLの解析に使用

class TikTokDownloader:
    def __init__(self, output_directory="downloaded_videos"):
        """
        TikTokDownloaderクラスを初期化する関数
        output_directory: 動画を保存するフォルダ名(初期値は"downloaded_videos")
        """
        # 動画を保存するフォルダの名前を設定
        self.output_folder = output_directory
        
        # フォルダが存在しない場合は新しく作成
        # exist_ok=Trueにすることで、既にフォルダがあってもエラーにならない
        os.makedirs(self.output_folder, exist_ok=True)
        
        # API設定を初期化する関数を呼び出し
        self.setup_api_config()
        
        # 初期化完了のメッセージを表示
        print(f"TikTokDownloader初期化完了 - 保存先: {self.output_folder}")

initメソッドはクラスの初期化を行う特別な関数です。ここで動画の保存先ディレクトリを設定し、API設定の初期化を呼び出します。

API通信設定機能

次に、クラス内にsetup_api_configメソッドを実装します。

    def setup_api_config(self):
        """
        API通信用の設定を準備する関数
        TikTok動画の情報を取得するためのAPIとヘッダー情報を設定
        """
        # TikTok動画の情報を取得するAPIのURL
        self.api_endpoint = "https://savetik.co/api/ajaxSearch"
        
        # HTTP通信で送信するヘッダー情報(ブラウザのふりをするため)
        self.request_headers = {
            # サーバーに「どんなデータでも受け取ります」と伝える
            'Accept': '*/*',
            # 「英語を優先して受け取ります」と伝える
            'Accept-Language': 'en-US,en;q=0.9',
            # 「フォームデータの形式で送信します」と伝える
            'Content-Type': 'application/x-www-form-urlencoded',
            # リクエストの送信元サイトを指定
            'Origin': 'https://savetik.co',
            # リクエストの優先度を設定
            'Priority': 'u=1, i',
            # 「このページからアクセスしました」という情報
            'Referer': 'https://savetik.co/en2',
            # ブラウザの種類とバージョンを伝える
            'Sec-Ch-Ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
            # 「モバイル端末ではありません」と伝える
            'Sec-Ch-Ua-Mobile': '?0',
            # 使っているOSの情報を伝える
            'Sec-Ch-Ua-Platform': '"Windows"',
            # リクエストの目的地を指定
            'Sec-Fetch-Dest': 'empty',
            # CORS(別サイトへの)リクエストであることを示す
            'Sec-Fetch-Mode': 'cors',
            # 同じサイト内でのリクエストであることを示す
            'Sec-Fetch-Site': 'same-origin',
            # ブラウザの詳細な情報(Chrome126を使っているように見せる)
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
            # AjaxリクエストであることをAPIに知らせる
            'X-Requested-With': 'XMLHttpRequest'
        }
        
        # 設定完了のメッセージを表示
        print("API設定完了")

このメソッドはクラス内で定義されているため、selfキーワードを使用してクラスの属性にアクセスできます。

HTTPヘッダーについて

HTTPヘッダーは、Webブラウザがサーバーと通信する際に送信する追加情報です。この設定により、プログラムが実際のブラウザのように動作してサーバーからデータを取得できます。

基本的な動作確認機能の実装

TikTokDownloaderクラス内に、設定が正しく動作するかを確認するメソッドを追加します。

    def check_connection(self):
        """
        API接続のテストを行う関数
        設定したAPIに実際に接続できるかを確認
        """
        try:
            # テスト用のダミーデータを準備
            test_data = {
                'q': 'https://www.tiktok.com/@test/video/test',  # テスト用URL
                'lang': 'en'  # 言語設定
            }
            
            # APIに実際にPOSTリクエストを送信してテスト
            response = requests.post(
                self.api_endpoint,  # 送信先のAPI URL
                data=test_data,  # 送信するデータ
                headers=self.request_headers,  # 送信するヘッダー情報
                timeout=10  # 10秒でタイムアウト
            )
            # responseにはサーバーからの返事が入っている
            
            # ステータスコードを確認(200なら成功、それ以外はエラー)
            if response.status_code == 200:
                print("✓ API接続テスト成功")
                return True  # 成功を表すTrueを返す
            else:
                print(f"✗ API接続エラー - ステータスコード: {response.status_code}")
                return False  # 失敗を表すFalseを返す
                
        except requests.exceptions.RequestException as error:
            # 通信エラーが発生した場合の処理
            print(f"✗ 接続テスト失敗: {error}")
            return False

このメソッドでは、APIエンドポイントに実際に接続を試行して、設定が正しく動作するかを確認します。timeout=10で10秒のタイムアウトを設定しています。

エラーハンドリング機能の実装

安全なHTTP通信のためのエラー処理機能をクラス内に追加します。

    def handle_request_error(self, error, url):
        """
        HTTPリクエストで発生したエラーを処理する関数
        error: 発生したエラーの情報
        url: エラーが発生したURL
        """
        # HTTPエラー(400番台、500番台のエラー)の場合
        if isinstance(error, requests.exceptions.HTTPError):
            print(f"HTTPエラーが発生しました - URL: {url}")
            print(f"ステータスコード: {error.response.status_code}")
        # 接続エラー(ネットワークに繋がらない等)の場合
        elif isinstance(error, requests.exceptions.ConnectionError):
            print(f"接続エラーが発生しました - URL: {url}")
            print("ネットワーク接続を確認してください")
        # タイムアウトエラー(時間内に応答がない)の場合
        elif isinstance(error, requests.exceptions.Timeout):
            print(f"タイムアウトエラーが発生しました - URL: {url}")
            print("時間をおいて再度お試しください")
        # その他のリクエストエラーの場合
        elif isinstance(error, requests.exceptions.RequestException):
            print(f"リクエストエラーが発生しました - URL: {url}")
            print(f"エラー詳細: {error}")
        # 予期しないエラーの場合
        else:
            print(f"予期しないエラーが発生しました: {error}")

isinstance()関数を使用してエラーの種類を判定し、それぞれに適した処理を実行します。これにより、どのような問題が発生したかを明確に把握できます。

テスト実行機能の実装

クラスの動作をテストするための機能を追加します。

def main():
    """
    TikTokDownloaderの基本動作をテストする関数
    クラスが正しく動作するかを確認
    """
    # プログラムのタイトルを表示
    print("=== TikTok動画ダウンローダー 設定テスト ===")
    
    # TikTokDownloaderクラスのインスタンス(実体)を作成
    downloader = TikTokDownloader()
    
    # 接続テストを実行
    print("\n--- API接続テスト実行中 ---")
    connection_result = downloader.check_connection()
    
    # テスト結果によって異なるメッセージを表示
    if connection_result:
        print("\n✓ 全ての設定が正常に動作しています")
    else:
        print("\n✗ 設定に問題があります")
        print("ネットワーク接続やAPI設定を確認してください")

# このファイルが直接実行された時のみmain関数を呼び出す
if __name__ == "__main__":
    main()

動作テスト実行

VSCodeのターミナルでプログラムを実行してテストします。

python src/video_downloader.py

出力結果

=== TikTok動画ダウンローダー 設定テスト ===
TikTokDownloader初期化完了 - 保存先: downloaded_videos
API設定完了

--- API接続テスト実行中 ---
✓ API接続テスト成功

✓ 全ての設定が正常に動作しています

Step3:WebスクレイピングでダウンロードURL取得機能の実装

このステップでは、TikTokの動画URLから実際のダウンロードリンクを取得するWebスクレイピング機能を実装します。BeautifulSoupを使用してHTML解析を行い、動画ファイルへの直接リンクを抽出していきます。

動画URL解析機能の実装

TikTokDownloaderクラス内に、動画URLを解析してダウンロードリンクを取得するメソッドを追加します。

    def extract_download_url(self, tiktok_url):
        """
        TikTokの動画URLから実際のダウンロード用URLを取得する関数
        tiktok_url: TikTokの動画URL
        """
        try:
            # APIに送信するデータを辞書形式で準備
            request_data = {
                'q': tiktok_url,  # TikTokの動画URL
                'lang': 'en'      # 言語設定(英語)
            }
            
            # 処理開始のメッセージを表示
            print(f"動画URL解析開始: {tiktok_url}")
            
            # APIにPOSTリクエストを送信
            api_response = requests.post(
                self.api_endpoint,           # 送信先のAPIエンドポイント
                data=request_data,           # 送信するデータ
                headers=self.request_headers # 送信するヘッダー情報
            )
            
            # HTTPエラーが発生した場合は例外を投げる
            api_response.raise_for_status()
            
            # APIから受け取ったHTMLを解析して、ダウンロードリンクを探す
            download_link = self.parse_download_link(api_response.text)
            
            # ダウンロードリンクが見つかった場合
            if download_link:
                print(f"✓ ダウンロードURL取得成功")
                return download_link
            else:
                print("✗ ダウンロードURLが見つかりませんでした")
                return None  # 見つからない場合はNoneを返す
                
        # HTTPエラー(400番台、500番台)が発生した場合
        except requests.exceptions.HTTPError as http_error:
            print(f"HTTPエラーが発生: ステータスコード {api_response.status_code}")
            self.handle_request_error(http_error, tiktok_url)
            return None
        # その他の通信エラーが発生した場合
        except requests.exceptions.RequestException as request_error:
            print(f"リクエストエラーが発生: {request_error}")
            self.handle_request_error(request_error, tiktok_url)
            return None
        # 予期しないエラーが発生した場合
        except Exception as unexpected_error:
            print(f"予期しないエラーが発生: {unexpected_error}")
            return None

このメソッドでは、TikTokのURLをAPIに送信し、api_response.textでHTML形式の返事を受け取ります。raise_for_status()メソッドでHTTPエラーの確認を行います。

HTML解析でダウンロードリンク抽出機能の実装

BeautifulSoupを使用してHTML内から動画のダウンロードリンクを探すメソッドをクラス内に追加します。

    def parse_download_link(self, html_content):
        """
        APIから取得したHTMLを解析してダウンロードリンクを見つける関数
        html_content: APIから受け取ったHTML文字列
        """
        try:
            # BeautifulSoupを使ってHTML文書を解析しやすい形に変換
            soup = BeautifulSoup(html_content, 'html.parser')
            
            # HTML内の全てのaタグ(リンクタグ)を取得
            all_link_tags = soup.find_all('a')
            
            # 見つかったリンクの数を表示
            print(f"検索対象のリンク数: {len(all_link_tags)}")
            
            # 各リンクタグを一つずつ確認
            for link_tag in all_link_tags:
                # リンクのテキスト内容を取得(前後の空白は削除)
                link_text = link_tag.text.strip()
                # リンクのclass属性を取得(ない場合は空のリスト)
                link_classes = link_tag.get('class', [])
                
                # 'Download MP4 HD'というテキストまたは'dl-success'クラスを持つリンクを探す
                if 'Download MP4 HD' in link_text or 'dl-success' in link_classes:
                    # href属性からダウンロードURLを取得
                    download_url = link_tag.get('href')
                    
                    # URLが存在する場合
                    if download_url:
                        print(f"ダウンロードリンク発見: {link_text}")
                        # URLに含まれる不要な文字(\")を除去
                        cleaned_url = download_url.replace('\\"', '')
                        return cleaned_url
            
            # 該当するリンクが見つからなかった場合
            print("該当するダウンロードリンクが見つかりませんでした")
            return None
            
        # HTML解析中にエラーが発生した場合
        except Exception as parse_error:
            print(f"HTML解析エラー: {parse_error}")
            return None

soup.find_all(‘a’)でHTML内の全てのリンクタグを取得し、その中から動画ダウンロード用のリンクを探します。link_tag.get(‘class’, [])でclass属性を安全に取得しています。

URL検証機能の実装

入力されたTikTokのURLが正しい形式かを確認するメソッドをクラス内に追加します。

    def validate_tiktok_url(self, url):
        """
        入力されたURLがTikTokの正しい形式かを確認する関数
        url: 検証するURL文字列
        """
        # TikTokの有効なドメイン(サイトアドレス)のリスト
        valid_domains = [
            'tiktok.com',        # 基本のドメイン
            'www.tiktok.com',    # wwwありのドメイン
            'm.tiktok.com',      # モバイル版のドメイン
            'vm.tiktok.com'      # 短縮URL用のドメイン
        ]
        
        # URLが入力されているかをチェック
        if not url or not isinstance(url, str):
            print("✗ URLが入力されていません")
            return False
        
        # URLがhttpsまたはhttpで始まっているかをチェック
        if not (url.startswith('https://') or url.startswith('http://')):
            print("✗ URLはhttps://またはhttp://で始まる必要があります")
            return False
        
        # TikTokの有効なドメインが含まれているかをチェック
        # any()は条件に合うものが一つでもあればTrueを返す
        is_valid_domain = any(domain in url.lower() for domain in valid_domains)
        
        # 有効なドメインが含まれていない場合
        if not is_valid_domain:
            print("✗ TikTokのURLではありません")
            return False
        
        # 全てのチェックをパスした場合
        print("✓ URLの形式が正しいです")
        return True

any()関数を使用して、URLに有効なTikTokドメインが含まれているかを確認します。url.lower()で大文字小文字を統一して比較しています。

統合処理機能の実装

URL検証から動画URL抽出までの一連の処理をまとめたメソッドをクラス内に追加します。

    def get_video_download_url(self, tiktok_url):
        """
        TikTokのURLから動画ダウンロードURLを取得する一連の処理をまとめた関数
        tiktok_url: TikTokの動画URL
        """
        # 処理開始のメッセージを表示
        print(f"\n=== 動画URL取得処理開始 ===")
        
        # Step1: URLの形式が正しいかを検証
        if not self.validate_tiktok_url(tiktok_url):
            return None  # 検証に失敗した場合は処理を終了
        
        # Step2: ダウンロードURLを抽出
        download_url = self.extract_download_url(tiktok_url)
        
        # 結果によって異なるメッセージを表示
        if download_url:
            print(f"✓ 動画ダウンロードURL取得完了")
            return download_url
        else:
            print("✗ 動画ダウンロードURL取得失敗")
            return None

このメソッドは、URL検証と動画URL抽出の処理を順番に実行し、結果を統合して返します。

テスト実行機能の更新

main関数を以下のように更新してください

def main():
    """
    TikTokDownloaderの動画URL取得機能をテストする関数
    実際のTikTokURLを使用してダウンロードURL抽出をテスト
    """
    # プログラムのタイトルを表示
    print("=== TikTok動画ダウンローダー URL取得テスト ===")
    
    # TikTokDownloaderクラスのインスタンスを作成
    downloader = TikTokDownloader()
    
    # 最初にAPI接続テストを実行
    print("\n--- API接続テスト実行中 ---")
    connection_result = downloader.check_connection()
    
    # API接続に問題がある場合は処理を終了
    if not connection_result:
        print("API接続に問題があります。処理を終了します。")
        return
    
    # テスト用のTikTokURL(実際のURLに置き換えてテスト可能)
    test_url = "https://www.tiktok.com/@test/video/test"
    
    # 動画URL取得テストを実行
    print(f"\n--- 動画URL取得テスト実行中 ---")
    download_url = downloader.get_video_download_url(test_url)
    
    # 結果によって異なるメッセージを表示
    if download_url:
        # URLが長い場合は最初の50文字だけ表示
        print(f"\n✓ テスト成功 - ダウンロードURL: {download_url[:50]}...")
    else:
        print(f"\n✗ テスト失敗 - ダウンロードURLを取得できませんでした")
        print("※ test_urlを実際のTikTok動画URLに変更してテストしてください")

# このファイルが直接実行された時のみmain関数を呼び出す
if __name__ == "__main__":
    main()

動作テスト実行

VSCodeのターミナルでプログラムを実行してテストします。

python src/video_downloader.py

出力結果

=== TikTok動画ダウンローダー URL取得テスト ===
TikTokDownloader初期化完了 - 保存先: downloaded_videos
API設定完了

--- API接続テスト実行中 ---
✓ API接続テスト成功

--- 動画URL取得テスト実行中 ---

=== 動画URL取得処理開始 ===
✓ URLの形式が正しいです
動画URL解析開始: https://www.tiktok.com/@test/video/test
検索対象のリンク数: 8
該当するダウンロードリンクが見つかりませんでした
✗ ダウンロードURL取得失敗

✗ テスト失敗 - ダウンロードURLを取得できませんでした
※ test_urlを実際のTikTok動画URLに変更してテストしてください

Step4:動画ダウンロード機能とユーザーインターフェースの実装

このステップでは、取得したダウンロードURLから実際に動画ファイルをダウンロードする機能と、ユーザーが操作しやすいコマンドラインインターフェースを実装します。複数の動画を連続してダウンロードできるシステムを構築していきます。

動画ファイルダウンロード機能の実装

TikTokDownloaderクラス内に、動画ファイルを実際にダウンロードして保存するメソッドを追加します。

既存のコードに以下のメソッドを追加してください

    def download_video_file(self, download_url, save_filename):
        """
        動画ファイルをダウンロードして指定された場所に保存する関数
        download_url: 動画のダウンロードURL
        save_filename: 保存するファイル名
        """
        try:
            # ダウンロード開始のメッセージを表示
            print(f"動画ダウンロード開始: {save_filename}")
            
            # URLに含まれる不要な文字(エスケープ文字)を削除
            cleaned_url = download_url.replace('\\"', '')
            
            # 実際に動画ファイルをダウンロード(30秒でタイムアウト)
            video_response = requests.get(cleaned_url, timeout=30)
            
            # HTTPエラーが発生した場合は例外を投げる
            video_response.raise_for_status()
            
            # ダウンロードした動画のファイルサイズを計算(MB単位)
            file_size_mb = len(video_response.content) / (1024 * 1024)
            print(f"ダウンロードサイズ: {file_size_mb:.2f} MB")
            
            # 保存先のフルパスを作成
            save_path = os.path.join(self.output_folder, save_filename)
            
            # 動画ファイルをバイナリモード('wb')で保存
            with open(save_path, 'wb') as video_file:
                video_file.write(video_response.content)
            
            # 保存完了のメッセージを表示
            print(f"✓ 動画保存完了: {save_path}")
            return True  # 成功を表すTrueを返す
            
        # HTTPエラー(400番台、500番台)が発生した場合
        except requests.exceptions.HTTPError as http_error:
            print(f"ダウンロード中にHTTPエラーが発生: {http_error}")
            return False
        # タイムアウトエラーが発生した場合
        except requests.exceptions.Timeout:
            print("ダウンロードがタイムアウトしました(30秒)")
            return False
        # その他の通信エラーが発生した場合
        except requests.exceptions.RequestException as request_error:
            print(f"ダウンロード中にエラーが発生: {request_error}")
            return False
        # ファイル保存時にエラーが発生した場合
        except IOError as io_error:
            print(f"ファイル保存中にエラーが発生: {io_error}")
            return False
        # 予期しないエラーが発生した場合
        except Exception as unexpected_error:
            print(f"予期しないエラーが発生: {unexpected_error}")
            return False

video_response.contentでバイナリデータ(動画ファイル)を取得し、‘wb’モードでファイルに書き込みます。timeout=30で30秒のタイムアウトを設定しています。

ファイル名生成機能の実装

ダウンロードした動画に適切なファイル名を自動生成するメソッドをクラス内に追加します。

    def generate_filename(self, download_url):
        """
        ダウンロードURLから適切なファイル名を自動生成する関数
        download_url: 動画のダウンロードURL
        """
        try:
            # URLを「/」で分割してリストにする
            url_parts = download_url.split('/')
            
            # URLの最後の部分を取得し、「?」以降のパラメータを除去
            video_id = url_parts[-1].split('?')[0]
            
            # ファイル名として使用可能な文字のみを定義
            safe_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
            
            # 安全な文字のみを残してファイル名を作成
            cleaned_id = ''.join(char for char in video_id if char in safe_chars)
            
            # ファイル名が短すぎる場合はタイムスタンプを追加
            if len(cleaned_id) < 5:
                import time  # 時間関連の機能をインポート
                timestamp = int(time.time())  # 現在時刻のタイムスタンプを取得
                cleaned_id = f"video_{timestamp}"
            
            # ファイル名に拡張子(.mp4)を追加
            filename = f"{cleaned_id}.mp4"
            
            # 生成されたファイル名を表示
            print(f"生成されたファイル名: {filename}")
            return filename
            
        # ファイル名生成中にエラーが発生した場合
        except Exception as filename_error:
            print(f"ファイル名生成エラー: {filename_error}")
            # エラー時は現在時刻を使ったフォールバック名を生成
            import time
            timestamp = int(time.time())
            return f"tiktok_video_{timestamp}.mp4"

url_parts[-1]でURLの最後の部分を取得し、split(‘?’)[0]でパラメータ部分を除去します。ファイル名に使用できない文字は除去して安全なファイル名を生成します。

統合ダウンロード処理機能の実装

URL取得から動画ダウンロードまでの全工程をまとめたメソッドをクラス内に追加します。

    def process_video_download(self, tiktok_url):
        """
        TikTokのURLから動画をダウンロードする全ての工程をまとめた関数
        tiktok_url: TikTokの動画URL
        """
        # 処理開始の区切り線とメッセージを表示
        print(f"\n{'='*50}")
        print(f"動画ダウンロード処理開始")
        print(f"URL: {tiktok_url}")
        print(f"{'='*50}")
        
        # Step1: ダウンロードURLを取得
        download_url = self.get_video_download_url(tiktok_url)
        if not download_url:
            print("✗ ダウンロードURL取得に失敗しました")
            return False  # 失敗時はFalseを返す
        
        # Step2: ファイル名を生成
        filename = self.generate_filename(download_url)
        
        # Step3: 動画ファイルをダウンロード
        download_success = self.download_video_file(download_url, filename)
        
        # 結果によって異なるメッセージを表示
        if download_success:
            print(f"✓ 動画ダウンロード完了: {filename}")
            return True  # 成功時はTrueを返す
        else:
            print("✗ 動画ダウンロードに失敗しました")
            return False  # 失敗時はFalseを返す

このメソッドは、URL取得、ファイル名生成、動画ダウンロードの3つのステップを順番に実行し、各段階の結果を確認します。

ユーザーインターフェース機能の実装

ユーザーが複数の動画を連続してダウンロードできるインターフェースをクラス内に追加します。

    def run_interactive_mode(self):
        """
        対話式の動画ダウンロードモードを実行する関数
        ユーザーが終了するまで繰り返し動画をダウンロード
        """
        # プログラムの説明とタイトルを表示
        print("\n" + "="*60)
        print("TikTok動画ダウンローダー - 対話モード")
        print("="*60)
        print("使い方:")
        print("1. TikTokの動画URLを入力してください")
        print("2. 'exit'と入力すると終了します")
        print("3. 'help'と入力すると使い方を再表示します")
        print("-"*60)
        
        # ダウンロード成功数をカウントするための変数
        download_count = 0
        
        # 無限ループでユーザー入力を受け付け
        while True:
            try:
                # ユーザーからの入力を受け取り、前後の空白を削除
                user_input = input("\nTikTok動画URL >>> ").strip()
                
                # 「exit」と入力された場合は終了
                if user_input.lower() == 'exit':
                    print(f"\n動画ダウンローダーを終了します")
                    print(f"総ダウンロード数: {download_count}個")
                    break  # ループから抜ける
                
                # 「help」と入力された場合は使い方を表示
                if user_input.lower() == 'help':
                    print("\n--- 使い方 ---")
                    print("TikTokの動画URLを入力: 動画をダウンロード")
                    print("exit: プログラムを終了")
                    print("help: この使い方を表示")
                    continue  # ループの最初に戻る
                
                # 何も入力されていない場合はスキップ
                if not user_input:
                    print("URLを入力してください")
                    continue
                
                # 動画ダウンロード処理を実行
                success = self.process_video_download(user_input)
                
                # ダウンロードが成功した場合はカウンターを増やす
                if success:
                    download_count += 1
                
            # Ctrl+Cでプログラムが中断された場合
            except KeyboardInterrupt:
                print(f"\n\nプログラムが中断されました")
                print(f"総ダウンロード数: {download_count}個")
                break  # ループから抜ける
            
            # 予期しないエラーが発生した場合
            except Exception as interface_error:
                print(f"エラーが発生しました: {interface_error}")
                print("続行しますか? (y/n)")
                continue_choice = input(">>> ").strip().lower()
                # 「y」または「yes」以外が入力された場合は終了
                if continue_choice not in ['y', 'yes']:
                    break

input().strip()でユーザー入力を取得し、前後の空白を除去します。KeyboardInterruptでCtrl+Cによる中断を検知し、適切に終了処理を行います。

テスト実行機能の更新

main関数を以下のように更新してください

def main():
    """
    TikTokDownloaderのフル機能をテストする関数
    対話式モードでユーザーからの入力を受け付け
    """
    # プログラムのタイトルを表示
    print("=== TikTok動画ダウンローダー ===")
    
    # TikTokDownloaderクラスのインスタンスを作成
    downloader = TikTokDownloader()
    
    # 最初にAPI接続テストを実行
    print("\n--- 初期接続テスト ---")
    connection_result = downloader.check_connection()
    
    # API接続に問題がある場合はプログラムを終了
    if not connection_result:
        print("API接続に問題があります。プログラムを終了します。")
        return
    
    # 接続テスト完了のメッセージを表示
    print("✓ 接続テスト完了")
    
    # 対話式モードを開始
    downloader.run_interactive_mode()

# このファイルが直接実行された時のみmain関数を呼び出す
if __name__ == "__main__":
    main()

動作テスト実行

VSCodeのターミナルでプログラムを実行してテストします。

python src/video_downloader.py

出力結果

=== TikTok動画ダウンローダー ===
TikTokDownloader初期化完了 - 保存先: downloaded_videos
API設定完了

--- 初期接続テスト ---
✓ API接続テスト成功
✓ 接続テスト完了

============================================================
TikTok動画ダウンローダー - 対話モード
============================================================
使い方:
1. TikTokの動画URLを入力してください
2. 'exit'と入力すると終了します
3. 'help'と入力すると使い方を再表示します
------------------------------------------------------------

TikTok動画URL >>> [ここにTikTokのURLを入力]

==================================================
動画ダウンロード処理開始
URL: https://www.tiktok.com/@example/video/example
==================================================

=== 動画URL取得処理開始 ===
✓ URLの形式が正しいです
動画URL解析開始: https://www.tiktok.com/@example/video/example
検索対象のリンク数: 15
ダウンロードリンク発見: Download MP4 HD
✓ ダウンロードURL取得成功
✓ 動画ダウンロードURL取得完了
生成されたファイル名: example_video.mp4
動画ダウンロード開始: example_video.mp4
ダウンロードサイズ: 12.45 MB
✓ 動画保存完了: downloaded_videos/example_video.mp4
✓ 動画ダウンロード完了: example_video.mp4

TikTok動画URL >>> exit

動画ダウンローダーを終了します
総ダウンロード数: 1個

Step5:プロジェクトをGitHubにアップロード

このステップでは、完成したTikTok動画ダウンローダープロジェクトをGitHubにアップロードし、ポートフォリオとして活用できる形にします。最終的なファイル整理とコードの公開を行っていきます。

.gitignoreファイルの更新

既存の.gitignoreファイルに、プロジェクト固有の除外設定を追加します。

VSCodeで「.gitignore」ファイルを開き、以下の内容を末尾に追加してください。

# Virtual environment
myenv/

# Downloaded videos
downloaded_videos/
*.mp4
*.mov
*.avi

# Cache files
__pycache__/
*.pyc
*.pyo

これらを追加する理由について説明します。

  • myenv/ 仮想環境フォルダはプロジェクト固有のため、リポジトリに含める必要がありません
  • downloaded_videos/ プログラム実行時にダウンロードされる動画フォルダを除外
  • *.mp4, *.mov, *.avi ダウンロードした動画ファイルを除外
  • pycache/ Pythonの実行時キャッシュフォルダを除外
  • *.pyc, *.pyo Pythonコンパイル済みファイルを除外

README.mdファイルの更新

リポジトリ作成時に生成されたREADME.mdファイルの内容を、プロジェクトの詳細情報に更新します。

VSCodeで「README.md」ファイルを開き、内容を以下のように全て置き換えてください。

# TikTok動画ダウンローダー

## プロジェクト内容

TikTokの動画URLから動画ファイルを直接ダウンロードできるツールです。WebスクレイピングとHTTP通信を使用して、TikTokの動画情報を取得し、ローカルに保存する機能を実装しています。PythonによるWeb API連携、HTMLパース、ファイル操作技術を学習することを目的として開発しました。

## プロジェクト構成

```
tiktok_downloader/
├── src/
│   └── video_downloader.py    # メインプログラム
├── downloaded_videos/         # ダウンロード動画保存フォルダ
├── requirements.txt           # 依存関係管理
├── README.md                  # プロジェクト説明書
└── .gitignore                # Git除外ファイル設定
```

## 必要要件/開発環境

- **Python 3.7以上**
- **VSCode** (開発環境)
- **Git** (バージョン管理)
- **インターネット接続** (動画ダウンロード用)

### 使用ライブラリ

- **requests** HTTP通信とAPI連携処理
- **beautifulsoup4** HTML解析とWebスクレイピング
- **os** ファイルシステム操作

## 機能

- **TikTokURL検証** 入力されたURLの形式確認と妥当性チェック
- **動画情報取得** WebスクレイピングによるダウンロードURL抽出
- **動画ダウンロード** 取得したURLからの動画ファイル取得
- **ファイル自動保存** ダウンロード動画の自動命名と保存
- **対話式インターフェース** ユーザーフレンドリーなコマンドライン操作
- **エラーハンドリング** 通信エラーやファイル操作エラーの適切な処理
- **ファイルサイズ表示** ダウンロード動画のサイズ確認
- **連続ダウンロード** 複数動画の連続処理機能

## 実行方法

### 1. リポジトリのクローン

```bash
git clone https://github.com/yourusername/tiktok_downloader.git
cd tiktok_downloader
```

### 2. 仮想環境の作成・アクティベート

**Windows**

```bash
python -m venv myenv
myenv\Scripts\activate
```

**macOS**

```bash
python3 -m venv myenv
source myenv/bin/activate
```

### 3. 依存関係のインストール

```bash
pip install -r requirements.txt
```

### 4. プログラムの実行

```bash
python src/video_downloader.py
```

実行後、対話式インターフェースが起動し、TikTokの動画URLを入力するとdownloaded_videosフォルダに動画が保存されます。

## 使用方法

1. プログラムを実行すると対話式モードが開始されます
2. `TikTok動画URL >>>` のプロンプトに動画のURLを入力します
3. 動画のダウンロードが自動で実行されます
4. `exit` と入力するとプログラムが終了します
5. `help` と入力すると使い方が表示されます

## データ形式について

- **入力データ** TikTokの動画URL(https://www.tiktok.com/...)
- **出力データ** MP4形式の動画ファイル
- **保存場所** downloaded_videosフォルダ内

## 注意事項

- このツールは教育目的で作成されています
- ダウンロードする動画の著作権を尊重してください
- 大量のダウンロードはサーバーに負荷をかける可能性があります

## 開発者

YuYu

プロジェクトのコミット・プッシュ

プロジェクトの全ての変更をGitHubに反映させましょう。

変更のステージングとコミット

  1. VSCodeの左側のアクティビティバーからソース管理アイコンをクリックします
  2. 変更内容セクションで、すべての変更ファイルを確認します
  3. 各ファイルの横にある「+」アイコンをクリックしてステージングします
  4. コミットメッセージ入力欄に「Add TikTok video downloader system with web scraping」と入力します
  5. コミット」ボタンをクリックします

GitHubへのプッシュ

  1. コミット完了後、「変更の同期」または「プッシュ」ボタンをクリックします
  2. 初回の場合、GitHub認証が求められる場合があります
  3. 認証完了後、ローカルの変更がGitHubリポジトリに反映されます

GitHubでの確認

プロジェクトが正常にアップロードされたか確認しましょう。

  1. ブラウザでGitHubリポジトリページを開きます
  2. 以下のファイルが正しくアップロードされていることを確認します
  • src/video_downloader.py (メインプログラムファイル)
  • requirements.txt (依存関係管理ファイル)
  • README.md (更新されたプロジェクト説明書)
  • .gitignore (更新された除外設定ファイル)
  1. README.mdが適切に表示され、プロジェクトの説明が読みやすく表示されていることを確認します
  2. ファイル一覧にmyenv/フォルダやdownloaded_videos/フォルダが含まれていないことを確認します(.gitignoreで除外されているため)

これで本格的なTikTok動画ダウンローダーシステムが完成し、GitHubでのポートフォリオ公開も完了しました。作成したプロジェクトは、就職活動や案件獲得時の実績として活用できる実用的なシステムとなっています。

まとめ

このプロジェクトを通じて、Pythonを使用したWebスクレイピングの基礎から実践的な応用まで幅広く学習することができました。

得られたスキル

  • requestsライブラリ – HTTP通信とAPI連携の基本操作
  • BeautifulSoup – HTML解析とWebスクレイピング技術
  • オブジェクト指向プログラミング – クラス設計と実装手法
  • エラーハンドリング – try-except文を使用した例外処理

得られた経験

  • 実際のAPIとの連携経験
  • Webスクレイピング技術の実践的な習得
  • ファイル操作とディレクトリ管理の実装
  • ユーザーインターフェース設計の基礎
  • GitHubを使用したバージョン管理の実践的経験

得られた成果物

  • 完全に動作するTikTok動画ダウンローダー
  • GitHubでのポートフォリオとして活用可能なプロジェクト
  • 完全なPythonソースコード

次に学ぶべきこと

  • Beautiful Soupの高度な機能(CSSセレクタの活用)
  • pandasを使用したデータ処理機能の追加
  • GUIアプリケーションの開発(tkinterの学習)
  • データベースへの保存機能の実装
  • スケジューリング機能による定期実行の実装

このプロジェクトから応用できること

  • YouTubeダウンローダーツールの開発による副業案件
  • 画像一括ダウンロードシステムの作成
  • Webサイトの定期監視ツールの構築
  • 商品価格監視システムの開発
  • ニュース記事自動収集ツールの作成
  • データ収集代行サービスの提供

このWebスクレイピング技術を基盤として、様々な分野でのデータ収集ニーズに対応できるサービスを開発することが可能です。特に、定期的な情報収集や監視が必要な業務では、高い価値を提供できる技術として活用できます。

この記事が気に入ったら
フォローしてね!

この記事が参考になった方はシェアしてね!
  • URLをコピーしました!

本コンテンツへの意見や質問

コメントする

目次