PythonでHTML正規表現を用いた小説サイトのカテゴリ抽出

Webスクレイピングの基本を学ぶために、シンプルな例として小説配信サイトからジャンル名を取得する方法を紹介します。この実装ではPython標準ライブラリのurllibre(正規表現)を活用し、外部パッケージに依存せずに処理を行います。

まず、対象となるWebページの構造を確認します。ターゲットはトップページにある「全カテゴリー」メニュー内のジャンルリンクです。これらの項目は以下のようなHTML構造で記述されています:

<dd><a href="/category/30020_f1_f1_f1_f1_f1_0_1"><em class="iconfont">&#xe630;</em><i>現代言情</i></a></dd>

この中から<i>タグで囲まれた日本語のジャンル名(例: 「現代言情」)を抽出することが目的です。

実装コード

以下の内容をnovel_scraper.pyとして保存し、実行してください。

import re
import urllib.request

class NovelCategoryExtractor:
    def __init__(self):
        self.fetch_and_parse()

    def fetch_and_parse(self):
        print("データ取得を開始します...")
        target_url = "https://www.readnovel.com"
        
        try:
            with urllib.request.urlopen(target_url, timeout=10) as res:
                html_content = res.read().decode('utf-8')
        except Exception as e:
            print(f"ページの取得に失敗しました: {e}")
            return

        # ジャンル部分のHTMLブロックを正規表現で抽出
        pattern_str = r'<dd><a href="/category/\d+_f1_f1_f1_f1_f1_0_1".*?>.*?<i>(.*?)</i></a></dd>'
        regex = re.compile(pattern_str)
        raw_matches = regex.findall(html_content)

        if not raw_matches:
            print("該当するカテゴリが見つかりませんでした。")
            return

        print("抽出されたジャンル一覧:")
        for index, title in enumerate(raw_matches, 1):
            print(f"{index}. {title}")

if __name__ == "__main__":
    extractor = NovelCategoryExtractor()

コードのポイント解説

  • URLリクエスト: urllib.request.urlopen()を使用してHTTPリクエストを送信し、レスポンスボディをUTF-8でデコードしています。
  • 正規表現パターン: 固定部分(/category/_f1_...)と可変部分(ID番号やジャンル名)を組み合わせて、必要なタグ構造のみマッチするように設計しています。(.*?)により<i>タグ内のテキストをキャプチャグループとして取り出しています。
  • 結果処理: findall()はキャプチャグループがあればその内容のみをリストで返すため、余計なタグ除去処理が不要になります。

注意点

対象サイトが将来的にデザインやHTML構造を変更した場合、正規表現のパターンも更新する必要があります。また、頻繁なリクエストはサーバー負荷になるため、学習目的以外での利用にはrobots.txtの確認や適切な間隔でのアクセスを心がけてください。

タグ: Python Webスクレイピング 正規表現 urllib HTML解析

9月9日 02:14 投稿