スポンサーリンク
Python

【Pythonで挑戦】Webスクレイピングで日経225の全銘柄リストを自動取得しよう!

Python
この記事は約10分で読めます。

【⚠️ご注意】 この記事で紹介するWebスクレイピングのコードは、本記事執筆時点(2025年8月29日)の「日経平均プロフィル」のサイト構造に基づいています。WebサイトのHTML構造は運営者によって予告なく変更されることがあり、その場合、この記事のコードは正常に動作しなくなる可能性があります。あらかじめご了承ください。

はじめに

「投資の分析のために、日経225の構成銘柄一覧が欲しい」 「プログラミングの学習として、実践的なデータ収集をしてみたい」

こんな風に思ったことはありませんか?日経平均株価(日経225)は、日本の株式市場を代表する重要な指標です。その構成銘柄をリストとして手元に置いておくと、経済の動向分析や投資戦略を練る上で非常に役立ちます。

しかし、公式サイト「日経平均プロフィル」を見てみると、銘柄は業種ごとに分かれて表示されており、これを一つひとつ手作業でコピー&ペーストするのは骨が折れる作業です。

そこで今回は、Pythonを使ったWebスクレイピングという技術を活用して、この日経225の全銘柄リストを自動で取得し、CSVファイルとして保存する方法を、一から丁寧に解説していきます。プログラミング初心者の方でも挑戦できるように、コードの意図や背景も詳しく説明しますので、ぜひ最後までお付き合いください。

取得したいファイル

取得したいファイルは以下の通りです。業種の取り方が少し難しそうです。

  • CSVファイル
  • ヘッダーは、コード,銘柄名,社名,業種
  • ファイル名はnikkei225_stocks.csvとする

こんな感じで取得します。

Webスクレイピングって何?

本題に入る前に、「Webスクレイピング」について簡単にご説明します。これは、Webサイト上にある情報をプログラムで自動的に収集する技術のことです。

例えば、毎日特定のニュースサイトから経済ニュースのヘッドラインだけを集めたり、ECサイトから特定商品の価格変動を追跡したりと、その活用範囲は多岐にわたります。人間がブラウザで見る情報を、プログラムが代わりに見て、必要な部分だけを抜き出してくれるイメージです。

ただし、スクレイピングを行う際には重要な注意点があります。

  • サイトの利用規約を確認する: サイトによってはスクレイピングを禁止している場合があります。
  • サーバーに負荷をかけない: 短時間に何度もアクセスすると、相手のサーバーに迷惑をかけてしまいます。

これらを守り、マナー良く情報を収集することが大切です。

準備するもの:Pythonと2つのライブラリをインストール

スクレイピングを始めるために、まずは環境を整えましょう。

  1. Python本体: まだPCにインストールしていない方は、公式サイトからダウンロードしてください。
  2. ライブラリ: Pythonには、便利な機能を追加できる「ライブラリ」という仕組みがあります。今回は以下の2つを使います。
    • requests: 私たちの代わりにWebサイトにアクセスし、HTMLファイルを取得してくれます。
    • BeautifulSoup4: requestsが持ってきたHTMLを、プログラムで扱いやすいように解析してくれる達人です。

ターミナル(Windowsならコマンドプロンプト)で以下のコマンドを実行すれば、簡単にインストールできます。

pip install requests beautifulsoup4

さあ、これで準備は万端です!

サイトの中身(html)の解析

ページを調べてみると、以下のことが分かりました。

  • ページ全体は、「医薬品」「電気機器」といった業種ごとのセクションに分かれている。
  • 各セクションは、<div class=”idx-index-components”>という箱で囲まれている。
  • 箱の中には、<h3 class=”idx-section-subheading”>という見出しに業種名が書かれている。
  • そして、同じ箱の中に<table>があり、その中に具体的な銘柄リストが格納されている。
  • テーブルの各行(<tr>)には、コード、銘柄名、社名がそれぞれセル(<td>)に分かれて入っている。

この調べた結果を元にPythonに「この目印を頼りに情報を取ってきて!」と指示を出すPGを書きます。

実践!Pythonコード徹底解説

それでは、いよいよコードの登場です。以下が、日経225の全銘柄を取得し、CSVファイルに保存するPythonスクリプトの全体像です。

import requests
from bs4 import BeautifulSoup
import csv

def get_nikkei225_stocks_from_html(html_content):
    """
    HTMLコンテンツから日経225の構成銘柄リストを解析して取得する関数
    """
    soup = BeautifulSoup(html_content, 'html.parser')
    
    # 業種ごとのセクション(div)をすべて取得
    sections = soup.find_all('div', class_='idx-index-components')
    
    if not sections:
        print("エラー: 銘柄情報セクションが見つかりませんでした。")
        return None

    all_stocks = []
    # 各セクションをループ処理
    for section in sections:
        # 業種名を取得
        industry_tag = section.find('h3', class_='idx-section-subheading')
        if not industry_tag:
            continue
        industry = industry_tag.text.strip()
        
        # セクション内のテーブルから銘柄情報を取得
        table = section.find('table')
        if not table:
            continue
            
        rows = table.find('tbody').find_all('tr')
        for row in rows:
            cols = row.find_all('td')
            if len(cols) >= 3:
                code = cols[0].text.strip()
                brand_name = cols[1].text.strip()
                company_name = cols[2].text.strip()
                
                # [コード, 銘柄名, 社名, 業種] の順でリストに追加
                all_stocks.append([code, brand_name, company_name, industry])

    return all_stocks

def save_to_csv(stocks, filename="nikkei225_stocks.csv"):
    """
    取得した銘柄リストをCSVファイルに保存する関数
    """
    if not stocks:
        print("データがありません。CSVファイルは作成されませんでした。")
        return
        
    header = ['コード', '銘柄名', '社名', '業種']
    
    try:
        # utf-8-sig を指定してExcelでの文字化けを防ぐ
        with open(filename, 'w', newline='', encoding='utf-8-sig') as f:
            writer = csv.writer(f)
            writer.writerow(header)
            writer.writerows(stocks)
        print(f"'{filename}' に銘柄情報を保存しました。")
    except IOError as e:
        print(f"エラー: ファイルの書き込みに失敗しました - {e}")

# --- メインの実行部分 ---
if __name__ == "__main__":
    url = "https://indexes.nikkei.co.jp/nkave/index/component?idx=nk225"
    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'
    }
    
    print(f"Webサイトからデータを取得しています... ({url})")
    
    try:
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        response.encoding = response.apparent_encoding
        
        stock_list = get_nikkei225_stocks_from_html(response.text)
        
        if stock_list:
            save_to_csv(stock_list)
            
    except requests.exceptions.RequestException as e:
        print(f"エラー: Webサイトへのアクセスに失敗しました - {e}")

コードのポイント解説

  • get_nikkei225_stocks_from_html関数:
    • これがスクレイピングの心臓部です。
    • soup.find_all(‘div’, class_=’idx-index-components’)で、先ほど分析した「業種の箱」をすべて見つけ出します。
    • for section in sections:で、箱を一つずつ順番に処理していきます。
    • 箱の中から業種名(h3)とテーブル(table)をfind()で見つけ、さらにテーブル内の全行(tr)をループ処理。
    • 最後に各行からセル(td)のテキストを抽出し、[コード, 銘柄名, 社名, 業種]という1件のデータを作成し、all_stocksリストに追加していきます
  • save_to_csv関数:
    • 集めたall_stocksリストを、見やすいCSV形式でファイルに保存します。
    • encoding=’utf-8-sig’は、CSVファイルをExcelで開いたときに日本語
  • メインの実行部分:
    • requests.get(url, headers=headers)で、実際にWebサイトにアクセスしています。headersを指定するのは、プログラムからのアクセスであることを隠し、一般的なブラウザからのアクセスに見せかけるためのテクニックです。
    • 取得したHTML(response.text)を先ほどの関数に渡し、最終的にCSV保存関数を呼び出して処理が完了します。

まとめ

Webスクレイピングは、一見難しそうに聞こえますが、「サイトの構造を分析し、その目印を頼りに情報を抽出する」というシンプルな原理で動いています。

この基本的な流れをマスターすれば、他の様々なサイトからも情報を集められるようになります。ぜひ、この記事をきっかけに、データ収集の自動化という強力な武器を手に入れて、あなたの分析や学習を次のレベルへと進めてみてください。

コメント

タイトルとURLをコピーしました