【Python自動化プロジェクト第1回】Webスクレイピングで価格監視!値下げ通知ツールの設計と情報抽出 🕵️‍♀️

「あの欲しかった商品、安くなったらすぐに知りたい!」
「Webサイトの価格を、毎日手動でチェックするのはもう疲れた…」
「Pythonで、実用的な自動化ツールをゼロから作ってみたい!」

こんにちは! Pythonプログラミング探検隊、隊長のPythonistaです! これまで私たちは、Pythonの基本から始まり、ファイル操作、データ分析、そしてWebスクレイピングの基礎まで、様々なスキルを身につけてきました。今回から始まる新シリーズでは、それらの知識を総動員して、非常に実用的でエキサイティングなプロジェクトに挑戦します!

その名も、「指定した商品の価格を監視し、設定した金額以下になったらDiscordに自動で通知するツール」の開発です! このシリーズを通して、あなたはデータ収集から処理、そして通知まで、自動化のワークフローを最初から最後まで体験することができます。

第1回となる今回は、このツールの**設計図**を描き、プロジェクトの心臓部である**Webページからの情報抽出**のテクニックをマスターします。さあ、あなたの日常をちょっと便利にする、本格的な自動化プロジェクトを始めましょう!


1.【最重要】スクレイピングの倫理とターゲット選定

本格的なプロジェクトに入る前に、Webスクレイピングにおける最も重要なルールを再確認しましょう。

  1. 利用規約の確認: 多くのECサイトでは、利用規約でスクレイピングを禁止しています。**(例: Amazonなど)**。必ずターゲットサイトの利用規約を確認し、許可されている範囲で利用してください。
  2. robots.txtの尊重: サイトの/robots.txt(例: https://example.com/robots.txt)には、プログラムによるアクセスに関するルールが書かれています。これを必ず守りましょう。
  3. サーバーへの配慮: 短時間に大量のアクセスを行うことは、相手のサーバーに大きな負荷をかけ、サービス妨害と見なされる可能性があります。アクセスには必ず適切な待機時間(time.sleep())を入れましょう。

このプロジェクトは、あくまで**技術学習を目的**としています。スクレイピングが許可されているサイトや、練習用に作られたサイト、あるいはAPIが提供されているサービスを対象に、ルールとマナーを守って実践してください。


2. プロジェクトの設計図を描こう

今回から数回にわたって作成するツールの全体像は以下の通りです。

  • 入力: 監視したい商品のURLをリストアップしたファイル。
  • 処理:
    1. URLリストを読み込む。
    2. 各URLにアクセスし、現在の価格を取得する。
    3. あらかじめ設定した「希望価格」と比較する。
    4. もし現在の価格が希望価格以下なら、通知メッセージを作成する。
  • 出力: Discordの特定チャンネルへの通知メッセージ。

第1回の今回は、この中の**「2. 各URLにアクセスし、現在の価格を取得する」**という、情報抽出の核心部分を実装します。


3. 準備:必要なライブラリ

Webスクレイピングには、おなじみの2つのライブラリが必要です。インストールがまだの方は、ターミナルでインストールしてください。

pip install requests beautifulsoup4 lxml
  • requests: Webページを取得する。
  • BeautifulSoup4: 取得したHTMLを解析する。
  • lxml: BeautifulSoupが使う高速な解析エンジン。

4. ターゲット分析:ブラウザ開発者ツールで宝の地図を手に入れる

スクレイピングの成否は、HTMLの構造をどれだけ正確に分析できるかにかかっています。そのための最強の武器が、ブラウザに内蔵されている**「開発者ツール」**です。

4.1. ターゲットページのHTML構造を覗いてみよう

今回は、練習用に以下のような架空の商品ページのHTMLがあると仮定します。(このHTMLをproduct.htmlとして保存し、ブラウザで開いて試してみてください)

<!DOCTYPE html>
<html lang="ja">
<head><title>すごいガジェット Pro</title></head>
<body>
    <div class="product-main">
        <h1 id="productTitle" class="product-name">すごいガジェット Pro Max</h1>
        <div class="price-block">
            <span class="price-label">価格:</span>
            <span class="price-value">¥19,800</span>
        </div>
    </div>
</body>
</html>
  1. このページをブラウザで開き、商品価格(¥19,800)の上で**右クリック**し、**「検証」**または**「要素を調査」**を選択します。
  2. 画面に開発者ツールが開き、対応するHTML部分がハイライトされます。

4.2. CSSセレクタを特定する

開発者ツールとにらめっこして、目的の情報を特定するための「住所」である**CSSセレクタ**を見つけ出します。

  • 商品名:

    タグで、id="productTitle"という一意のIDが付いています。IDを指定するのが最も確実なので、CSSセレクタは**#productTitle**となります。(#はIDを意味します)
  • 価格: タグで、class="price-value"というクラス名が付いています。クラス名を指定するには.(ドット)を使うので、CSSセレクタは**.price-value**となります。

この「CSSセレクタを見つけ出す」探偵のような作業が、スクレイピングの面白さであり、最も重要なスキルです。


5. 実装:情報抽出関数を作成する

分析が終われば、あとはコードに落とし込むだけです。特定のURLから商品名と価格を抽出する関数を作成しましょう。

import requests
from bs4 import BeautifulSoup

def get_product_info(url):
    """
    指定されたURLから商品名と価格を抽出する関数
    Args:
        url (str): ターゲットとなる商品ページのURL
    Returns:
        dict: 'name'と'price'を含む辞書。取得失敗時はNoneを返す。
    """
    # ブラウザからのアクセスを装うためのヘッダー
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
        'Accept-Language': 'ja-JP,ja;q=0.9,en-US;q=0.8,en;q=0.7'
    }

    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status() # エラーがあれば例外を発生

        soup = BeautifulSoup(response.text, 'lxml')

        # CSSセレクタを使って要素を特定
        name_element = soup.select_one('#productTitle')
        price_element = soup.select_one('.price-value')

        # 要素が見つかった場合のみテキストを取得
        name = name_element.text.strip() if name_element else None
        price_str = price_element.text.strip() if price_element else None
        
        if name and price_str:
            # 価格から不要な文字(¥やカンマ)を取り除き、数値に変換
            price = int(re.sub(r'[¥,¥]', '', price_str))
            return {'name': name, 'price': price}
        else:
            print("エラー: 商品名または価格が見つかりませんでした。")
            return None

    except requests.exceptions.RequestException as e:
        print(f"エラー: サイトへのアクセスに失敗しました - {e}")
        return None
    except Exception as e:
        print(f"エラー: 処理中に予期せぬエラーが発生しました - {e}")
        return None

# --- 実行テスト ---
if __name__ == '__main__':
    # 実際のWebサイトのURLで試す場合は、利用規約を必ず確認してください
    # test_url = "ここにテストしたい商品のURL"
    # product_info = get_product_info(test_url)
    # if product_info:
    #     print(f"商品名: {product_info['name']}")
    #     print(f"価格: {product_info['price']}円")
    print("get_product_info関数が定義されました。実際のURLで試す際は、利用規約とマナーを守ってください。")

価格を抽出した後、re.sub()を使って「¥」や「,」といった計算の邪魔になる文字を取り除き、int()で数値に変換しているのがポイントです。これにより、後の価格比較が容易になります。


まとめと次回予告

今回は、価格監視&通知ツールの開発に向けた、最も重要な第一歩を踏み出しました。

  • スクレイピングを行う上での倫理とマナーを再確認した。
  • ブラウザの開発者ツールを使い、WebページのHTML構造を分析して目的の情報を特定する方法を学んだ。
  • requestsBeautifulSoup4を使い、特定のCSSセレクタを手がかりに商品名と価格を抽出する関数を実装した。

これで、あなたもどんなWebページからでも、狙った情報を抜き出すための基本的なスキルと手順をマスターしました。

さて、商品情報が一つ取得できるようになったら、次はいよいよこの関数を使って、**価格を継続的にチェックし、安くなったらメッセージを生成する**という、ツールの「頭脳」部分を実装していきます。

次回、第2回では、複数の商品をリストで管理し、それぞれの価格を希望価格と比較し、条件を満たした場合に通知メッセージを作成する、**メインの監視ロジック**を構築します。お楽しみに!

その他の投稿はこちら

コメント

このブログの人気の投稿

タイトルまとめ

これで迷わない!WindowsでPython環境構築する一番やさしい方法 #0

【Python標準ライブラリ完結!】11の冒険をありがとう!君のPython力が飛躍する「次の一歩」とは? 🚀