【Webスクレイピング応用・完結編】複数ページ巡回(クローリング)とPandas/Matplotlibでの分析・可視化 🤖

「1ページ分のデータは取れたけど、サイトにある何十ページもの情報を全部集めるにはどうすればいいの?」
「スクレイピングで集めたデータを、ただ眺めるだけじゃなくて、何か意味のある分析をしてみたい!」
「データ収集から分析、グラフ化まで、一連の流れを全部Pythonで完結させたい!」

こんにちは! Webスクレイピング探検隊、隊長のPythonistaです! 前回の第2回では、ブラウザの開発者ツールを駆使して現実的なニュースサイトのHTMLを分析し、記事の見出しとリンクを抽出してCSVファイルに保存する、という実践的なスキルをマスターしましたね。

いよいよシリーズ最終回となる今回は、これまでの知識を総動員し、Webスクレイピングの冒険を完結させます! 今回のテーマは、

  • 単一ページから、複数ページを自動で巡回する「クローリング」へのステップアップ
  • クローリングで収集した大量のデータを、Pandasで読み込み、簡単なテキスト分析を行う
  • 分析結果をMatplotlibでグラフ化し、データから洞察を得る

という、データ収集から分析・可視化までの一連のデータ分析プロジェクトです。この記事を終える頃には、あなたはWebから自力で情報を集め、それを意味のある形に変えるという、データサイエンティストのような体験をすることができるでしょう。さあ、冒険のクライマックスです!


1. 準備:これまでの知識と新しいHTMLサンプル

今回は、これまでに学んだ多くのライブラリを組み合わせます。インポート文も賑やかになりますね!

import requests
from bs4 import BeautifulSoup
import csv
import time # クローリングのマナーとして必須!
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
import re

今回のターゲット:複数ページのニュースサイト

複数ページを巡回するために、前回作成したmock_news.htmlを少し改造し、ページネーション(ページ送り)のリンクを追加したサンプルを用意します。以下の2つのHTMLファイルを作成し、スクリプトと同じディレクトリに保存してください。

mock_news_page1.html:

<!DOCTYPE html>
<html lang="ja">
<!-- (head部分は省略) -->
<body>
    <h1>TechTrend Today - 1ページ目</h1>
    <div class="article-list">
        <div class="article-entry"><h2 class="article-title"><a href="/news/001">Python、次期バージョンで画期的な新機能を追加か</a></h2></div>
        <div class="article-entry"><h2 class="article-title"><a href="/news/002">AIが描く未来の都市デザインとは</a></h2></div>
        <div class="article-entry"><h2 class="article-title"><a href="/news/003">量子コンピュータ、実用化への大きな一歩</a></h2></div>
    </div>
    <div class="pagination">
        <a href="mock_news_page2.html">次のページへ >></a>
    </div>
</body>
</html>

mock_news_page2.html:

<!DOCTYPE html>
<html lang="ja">
<!-- (head部分は省略) -->
<body>
    <h1>TechTrend Today - 2ページ目</h1>
    <div class="article-list">
        <div class="article-entry"><h2 class="article-title"><a href="/news/004">データサイエンスで変わる、新しい農業の形</a></h2></div>
        <div class="article-entry"><h2 class="article-title"><a href="/news/005">PythonとRust、注目の連携フレームワークが登場</a></h2></div>
    </div>
    <div class="pagination">
        <span>これ以上ページはありません</span>
    </div>
</body>
</html>

2. ステップ1:複数ページを巡回する「クローラー」の実装

単一ページの情報を取得する「スクレイパー」から、複数のページをたどる「クローラー」へと進化させましょう。

2.1. クローリングのロジック

基本的な考え方はシンプルです。

  1. 最初のページにアクセスしてデータを抽出する。
  2. そのページに「次のページへ」のリンクがあるか探す。
  3. リンクがあれば、そのリンク先のURLにアクセスしてデータを抽出する。
  4. 「次のページへ」のリンクがなくなるまで、2と3を繰り返す。

このロジックを、forループやwhileループを使って実装します。今回は、取得するページ数をあらかじめ決めておく簡単なforループで実装してみましょう。

2.2. スクリプトの統合とクローリング機能の追加

前回のスクリプトをベースに、複数ページを巡回する機能を追加します。

# 前回のextract_articles_from_html関数とsave_to_csv関数は再利用
# (ここでは省略。完全なコードは最後に掲載します)

def main_crawler():
    base_url = "http://example.com/" # 架空のベースURL
    
    # 今回はローカルファイルなので、ファイル名のリストを用意
    target_files = ['mock_news_page1.html', 'mock_news_page2.html']
    
    all_articles = [] # 全てのページから集めた記事を格納するリスト
    
    for page_file in target_files:
        print(f"\n'{page_file}' をスクレイピング中...")
        
        try:
            # ローカルファイルを開く (実際のWebサイトなら requests.get() を使う)
            with open(page_file, 'r', encoding='utf-8') as f:
                content = f.read()
            
            # 1ページ分の記事を抽出
            articles_on_page = extract_articles_from_html(content, base_url) # (後で関数を少し改造)
            
            if articles_on_page:
                all_articles.extend(articles_on_page) # 結果を総合リストに追加
                print(f"  {len(articles_on_page)}件の記事を抽出しました。")
            
            # 【重要】相手サーバーに負荷をかけないためのマナー
            print("  1秒待機します...")
            time.sleep(1)
            
        except FileNotFoundError:
            print(f"  エラー: ファイル '{page_file}' が見つかりません。")
        except Exception as e:
            print(f"  予期せぬエラー: {e}")
            
    print(f"\nクローリング完了。合計 {len(all_articles)}件の記事を収集しました。")
    
    # 全ての記事データをCSVに保存
    save_to_csv(all_articles, 'all_news_headlines.csv')

# (extract_articles_from_html関数は、相対URLを絶対URLに変換するよう少し改造が必要)
# from urllib.parse import urljoin  # URLを結合するために使う
# url = urljoin(base_url, link.get('href')) のようにする

このロジックで、複数のページからデータを集めて、一つのリストall_articlesに格納することができました。time.sleep(1)が、実際のWebサイトをクローリングする際の重要なマナーです。


3. ステップ2:Pandasによるデータ分析

収集したデータをCSVファイルに保存したら、次はそのデータを分析します。ここからがPandasの出番です!

3.1. CSVファイルをDataFrameに読み込む

import pandas as pd

csv_file_path = 'all_news_headlines.csv'
try:
    df = pd.read_csv(csv_file_path)
    print("\n--- CSVから読み込んだDataFrame ---")
    print(df)
except FileNotFoundError:
    print(f"ファイル '{csv_file_path}' が見つかりません。先にクローラーを実行してください。")
    df = pd.DataFrame() # 空のDataFrameを作成

3.2. 簡単なテキスト分析:単語の頻度をカウント

収集した記事のタイトルに、どのような単語がよく使われているかを調べてみましょう。collections.Counterが役立ちます。

from collections import Counter
import re

# dfが読み込まれている前提
if not df.empty:
    # 全てのタイトルを一つの大きな文字列に結合
    all_titles = ' '.join(df['title'])
    
    # 正規表現で単語(アルファベットのみ)を抽出
    words = re.findall(r'[a-zA-Z]+', all_titles.lower())
    
    # Counterで単語の出現頻度をカウント
    word_counts = Counter(words)
    
    print("\n--- タイトル内の単語頻度 Top 5 ---")
    # most_common(N)で上位N件を取得
    for word, count in word_counts.most_common(5):
        print(f"{word}: {count}回")

(注:日本語の単語頻度を正確に行うには、MeCabやJanomeといった形態素解析ライブラリが必要になります。今回は簡単にするため、アルファベットの単語のみを対象としています。)


4. ステップ3:Matplotlibによる可視化

最後に、分析結果を棒グラフにして視覚的に分かりやすく表現しましょう。

# word_counts が計算済みとする
if 'word_counts' in locals() and word_counts:
    # 上位10件のデータを準備
    top_10_words = word_counts.most_common(10)
    labels, values = zip(*top_10_words) # ラベルと値のリストに分割
    
    plt.style.use('ggplot')
    plt.figure(figsize=(10, 6))
    
    # 水平棒グラフを作成
    plt.barh(labels, values, color='#3498db')
    
    # 上位が上に来るようにY軸を反転
    plt.gca().invert_yaxis()
    
    plt.title('ニュースタイトル頻出単語 Top 10')
    plt.xlabel('出現回数')
    plt.tight_layout()
    plt.show()

これで、Webからデータを自動で収集し、分析し、その結果をグラフで表現するという、データ分析の基本的なパイプラインを全てPythonで完遂することができました!

完全なコードはこちらに記載


まとめ:Webスクレイピング入門シリーズ完結!

3回にわたるWebスクレイピング入門シリーズ、お疲れ様でした!このシリーズを通して、私たちは以下の壮大な旅をしました。

  • 第1回: `requests`と`BeautifulSoup4`を使い、単一のWebページから情報を抽出する基本をマスターした。
  • 第2回: ブラウザの開発者ツールでHTMLを分析し、抽出したデータをCSVファイルに保存する実践的なスキルを身につけた。
  • そして今回: 複数ページを自動巡回する「クローリング」にステップアップし、収集したデータを`Pandas`と`Matplotlib`で分析・可視化する、一連のプロジェクトを完成させた。

Webスクレイピングは、インターネットという無限の情報源からデータを取得するための強力な技術です。そして、そのデータを分析・可視化することで、これまで見えなかった新しい発見や洞察を得ることができます。今回学んだワークフローは、そのための非常に重要な第一歩です。

ぜひ、今回作成したクローラーをベースに、あなたの興味のあるサイト(ルールとマナーは必ず守ってくださいね!)からデータを集め、独自の分析に挑戦してみてください。あなたのプログラミングの世界は、ここからさらに大きく広がっていきます!

これまでの探検、ありがとうございました! Happy Scraping & Analyzing! 🤖

【Pythonスクレイピング実践】Amazonの商品情報を自動収集するツールの作り方(※学習・研究目的限定)

その他の投稿はこちら

コメント

このブログの人気の投稿

タイトルまとめ

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

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