はじめに: Webスクレイピングとは

Webスクレイピングの概要

Webスクレイピングとは、プログラム(スクリプト)を使ってWebページから必要な情報を自動的に取得する手法です。Excelにコピペしていた作業を自動化したり、大量のデータを効率的に集めたりする際に役立ちます。特に、企業内で定期的にモニタリングしている公開情報や社内ポータルサイトの更新情報を収集して、社内データベースと照合するケースでは、大きく作業効率を向上させることができます。

倫理的・法的注意点

  • 利用規約の遵守: スクレイピング対象のWebサイトが示している利用規約やrobots.txtを必ず確認しましょう。
  • アクセス頻度の節度: 過剰な頻度でサーバーにアクセスすると、サイト運営者に負担をかけたり、アクセスブロックされたりする可能性があります。
  • 社内外の情報取扱い: 取得したデータの扱いには注意し、権利やプライバシーを侵害しないように運用しましょう。

Step 1. Python環境の準備

必要なライブラリのインストール

Webスクレイピングでは主に以下のライブラリを使用します。

  1. requests: Webページの取得(HTTPリクエスト)
  2. BeautifulSoup (beautifulsoup4): HTML解析・情報抽出

インストール方法(ターミナルまたはコマンドプロンプト)

pip install requests
pip install beautifulsoup4

※Pythonがインストールされていない場合は、Python公式サイトからダウンロード・インストールしてください。

開発用エディタ・環境

  • VS CodePyCharm、またはJupyter Notebookなどを使うと開発がしやすいです。
  • 依存ライブラリ管理にはvirtualenvcondaなどの仮想環境を活用することを推奨します。

Step 2. Webページの取得

まずはWebページのHTMLソースを取得します。ここではrequestsライブラリを使います。

import requests

# 取得したいURLを指定
url = 'https://example.com'

try:
    response = requests.get(url, timeout=10)  # タイムアウトを10秒に設定
    response.raise_for_status()               # HTTPエラーが返ってきた場合は例外を投げる
    html_content = response.text
except requests.exceptions.RequestException as e:
    print(f"ページの取得に失敗しました: {e}")
    html_content = None

if html_content:
    print("ページの取得に成功しました。")
    # ここではprintせず、この後の解析に備えて変数html_contentに保管

ポイント

  • timeout=10でサーバーから応答が無い場合の待ち時間を短く設定し、無限に待ち続けないようにします。
  • response.raise_for_status()で、ステータスコードが200番台以外の場合に自動的にエラーを発生させることができます。
  • エラーが出た場合は例外処理(try-except)でキャッチし、原因調査・ログ出力などを行いましょう。

Step 3. HTMLの解析と情報抽出

取得したHTMLをPythonで扱いやすくするために、BeautifulSoupを使って解析(パース)します。

from bs4 import BeautifulSoup

if html_content:
    soup = BeautifulSoup(html_content, 'html.parser')

    # 例: 記事タイトルが <h2 class="article-title"> でマークアップされている場合
    titles = soup.find_all('h2', class_='article-title')
    for title in titles:
        print(title.get_text())

    # 例: リンクURLをすべて取得
    links = soup.find_all('a')
    for link in links:
        href = link.get('href')
        text = link.get_text()
        # 不要な空白があれば除去する
        text = text.strip()
        print(f"リンクテキスト: {text}, URL: {href}")

よく使うHTMLタグと属性

  • div / span / p: 一般的なテキストコンテンツ
  • a (anchorタグ): リンク要素
  • img: 画像要素
  • table / tr / td: 表組み要素

BeautifulSoupの主要メソッド

  • find(tag, attrs={...}): 条件に合う要素を最初に1つ取得
  • find_all(tag, attrs={...}): 条件に合う全ての要素をリストで取得
  • get_text(): 要素のテキスト部分を取得
  • get('属性名'): 要素内の属性値を取得(例: href

Step 4. データの保存方法

スクレイピングしたデータを蓄積・照合するには、データベースを活用するのがおすすめです。ここでは組み込みのSQLiteデータベースを例に紹介します。

SQLiteのセットアップ

import sqlite3

# test.db というファイル名でSQLiteに接続 (存在しない場合は自動的に作成)
conn = sqlite3.connect('test.db')
cursor = conn.cursor()

# テーブルが存在しない場合は作成
cursor.execute('''
CREATE TABLE IF NOT EXISTS articles (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT NOT NULL,
    url TEXT,
    scraped_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()

# データの挿入例
title = "サンプル記事"
url = "https://example.com/sample-article"
cursor.execute('''
    INSERT INTO articles (title, url)
    VALUES (?, ?)
''', (title, url))
conn.commit()

# データベースとの接続を終了
cursor.close()
conn.close()

社内データベースとの連携

  • SQL ServerやMySQL、PostgreSQLなどの商用・オープンソースDBとも同様にPythonから接続できます。
  • 既存の社内データベースに新しいテーブルを作る、もしくは既存テーブルにカラムを追加してスクレイピングデータを保存するといった運用が考えられます。
  • 企業のセキュリティポリシーに従い、接続設定(ID・パスワード)の管理に注意してください。

Step 5. 定期実行の設定(スケジューリング)

手動でスクリプトを実行するだけでは、定期的な情報収集は難しくなります。下記のような方法で自動化しましょう。

UNIX系 (Linux, macOS) の場合: cron

  1. ターミナルでcrontab -eを実行
  2. 実行間隔を指定し、Pythonスクリプトへのパスを書き込みます。例: 毎日午前3時に実行0 3 * * * /usr/bin/python3 /home/username/scrape_script.py

Windowsの場合: タスク スケジューラ

  1. スタートメニュー→「タスク スケジューラ」を開く
  2. 「基本タスクの作成」から名前・トリガー(スケジュール)・操作を設定
  3. 「プログラムの開始」でPython実行ファイル(python.exe)とスクリプトのパスを指定

スケジューリングの頻度設定

  • 更新頻度の高いサイトなら数時間ごと、頻度の低いサイトなら1日1回程度にするなど、アクセス過多にならないよう調整してください。
  • 失敗時のリトライ回数やログ出力も設定しておくと安心です。

Step 6. データの照合・検証とエラー対応

社内DBとの照合

  • すでに保存されている情報(URLや記事タイトルなど)と新規取得データを比較し、新規レコードだけを追加する、または更新があったレコードだけを上書き保存するなどの処理を実装します。
  • 比較のために、タイトルやURLをキーとした検索・照合クエリを用意すると便利です。
def save_if_not_exists(title, url, conn):
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM articles WHERE url = ?", (url,))
    result = cursor.fetchone()
    if not result:
        cursor.execute("INSERT INTO articles (title, url) VALUES (?, ?)", (title, url))
        conn.commit()
        print("新規データを追加しました:", title)
    else:
        print("すでに登録済みのデータです:", title)
    cursor.close()

エラー・不一致への対処

  • スクレイピング失敗時(HTTPエラーやパースエラー)は、ログファイルなどにエラーの詳細を記録しましょう。
  • 新しく取得したデータが既存データと大きく異なる場合、フォーマット変更やサイトリニューアルの可能性があります。定期的にコードのメンテナンスを行う必要があります。

Step 7. まとめと次のステップ

まとめ

  1. Webスクレイピングの基礎requestsでWebページを取得し、BeautifulSoupでHTMLを解析する。
  2. データの保存・照合: SQLiteや社内DBを用いて情報を蓄積し、更新差分をチェックして管理する。
  3. 定期実行cronやタスク スケジューラで定期的にスクリプトを走らせることで自動化を実現。
  4. エラー対策とメンテナンス: サイト構造の変化やネットワーク障害などに備えて、エラー処理やログ管理を整備する。

次のステップ

  • 高度なスクレイピング: サイトによってはJavaScriptで動的にページが生成されるため、SeleniumPlaywrightなどのヘッドレスブラウザが必要になる場合があります。
  • API活用: 公開APIを提供しているサイトからはWebスクレイピングではなくAPI経由でデータを取得するとより安定して取得できるケースがあります。
  • データ分析・可視化: 取得データをPandasで加工し、MatplotlibやSeabornでグラフ化してレポートを自動生成することで、社内で共有しやすくなります。

サンプルコード(再掲)

以下は基本的な「Webページ取得」と「HTML解析」の例です。実際のサイト構造に合わせて要素(タグやクラス名)を調整してください。

import requests
from bs4 import BeautifulSoup

def scrape_example():
    try:
        response = requests.get('https://example.com')
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        print(f"リクエストに失敗しました: {e}")
        return

    soup = BeautifulSoup(response.text, 'html.parser')

    # 例: 記事タイトル取得
    titles = soup.find_all('h2', class_='article-title')
    for title in titles:
        print(title.get_text())

最後に

Webスクレイピングは、データを自動で集める強力な手段です。しかし、その運用にあたっては常にサイトの利用規約とマナーを守り、過剰アクセスや違法行為を避けることが重要になります。定期的にサイト構造の変更やスクレイピングの負荷を確認しつつ、必要に応じてスクリプトの改修を行いましょう。

こうした基本的な流れを押さえたうえで、ぜひ継続的に技術を磨いていってください。自動化の仕組みを整えれば、社内に必要な情報をいつでもタイムリーに取得・集約できるようになり、業務の効率化とデータドリブンな意思決定の支援に繋がります。