対象タグの種類
HTML フォームを構成する主要タグは以下の 3 種類だ。
| タグ | 用途 | 典型例 |
|---|---|---|
<input> | 単一値の入力。type 属性で挙動が変わる。 | text / password / email / checkbox / radio / hidden / file / date など |
<select> | ドロップダウン・複数選択。 | 都道府県・性別・権限種別 |
<textarea> | 複数行テキスト入力。 | コメント・備考・本文 |
📌 button・submit は除外する
本シリーズでは データ入力に使う要素のみを抽出対象とする。type="submit" や type="button" の <input> はエンティティとして意味がないため除外する。
input type 属性の一覧
| type 値 | 用途 | 抽出対象 |
|---|---|---|
text | 一般テキスト入力 | ✅ |
password | パスワード | ✅ |
email | メールアドレス | ✅ |
number | 数値入力 | ✅ |
tel | 電話番号 | ✅ |
date | 日付 | ✅ |
checkbox | チェックボックス | ✅ |
radio | ラジオボタン | ✅ |
hidden | 隠しフィールド | ✅(セキュリティ監査用) |
file | ファイルアップロード | ✅ |
submit | 送信ボタン | ❌ 除外 |
button | 汎用ボタン | ❌ 除外 |
reset | リセットボタン | ❌ 除外 |
収集対象の属性一覧
| 属性名 | 対象タグ | 意味 |
|---|---|---|
name | 全タグ | フォーム送信時のキー名。DB カラム候補として最重要。 |
id | 全タグ | HTML 上の識別子。label との紐付けに使う。 |
type | input | 入力の種類。DB 型推定に使う。 |
placeholder | input / textarea | 入力例・ヒント文言。 |
required | 全タグ | 必須入力かどうか。NOT NULL 制約の判断材料。 |
maxlength | input / textarea | 最大文字数。VARCHAR の桁数設計に使う。 |
minlength | input / textarea | 最小文字数。 |
min / max | input[type=number/date] | 数値・日付の範囲。CHECK 制約候補。 |
pattern | input | 正規表現バリデーション。 |
value | input / option | デフォルト値・送信値。 |
multiple | select / input[file] | 複数選択可否。 |
label タグの取得戦略
フォームの「表示名」として最も重要なのが <label> タグのテキストだ。
label と input の紐付けには 3 つのパターンがある。
<!-- パターン 1: for 属性 + id 属性 -->
<label for="username">ユーザー名</label>
<input id="username" type="text" name="username">
<!-- パターン 2: label でラップ -->
<label>
メールアドレス
<input type="email" name="email">
</label>
<!-- パターン 3: aria-label 属性(label タグなし)-->
<input type="search" name="q" aria-label="キーワード検索">
dataclass によるエンティティ定義
収集した属性を格納する Python dataclass を定義する。 これが PART 06・07 での実装の中核となる。
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class InputEntity:
"""HTML フォーム内の 1 つの入力要素を表すエンティティ"""
# ---- 基本識別情報 ----
tag: str # "input" / "select" / "textarea"
type: str # input type 属性値 or "select" / "textarea"
name: Optional[str] = None # name 属性(DB カラム候補)
id: Optional[str] = None # id 属性
# ---- 表示情報 ----
label: Optional[str] = None # 関連 label のテキスト
placeholder: Optional[str] = None # placeholder 属性
# ---- バリデーション情報 ----
required: bool = False
maxlength: Optional[str] = None
minlength: Optional[str] = None
min: Optional[str] = None
max: Optional[str] = None
pattern: Optional[str] = None
# ---- 値情報 ----
value: Optional[str] = None # デフォルト値
options: list[str] = field(default_factory=list) # select の選択肢
# ---- メタ情報 ----
form_id: Optional[str] = None # 所属する form タグの id
page_url: Optional[str] = None # 抽出元 URL
📌 dataclass を使う理由
辞書(dict)でも同等のデータを持てるが、dataclass にすると型ヒントが付き、IDE の補完が効き、__repr__ が自動生成されてデバッグしやすい。JSON 変換も dataclasses.asdict() 一発でできる。
import json
import dataclasses
from extractor.models import InputEntity
entity = InputEntity(
tag="input",
type="text",
name="username",
id="username",
label="ユーザー名",
required=True,
maxlength="50",
)
# dataclass → dict → JSON
print(json.dumps(dataclasses.asdict(entity), ensure_ascii=False, indent=2))
✅ 次の章では…
PART 06 では requests + BeautifulSoup を使って、このモデルに実際のデータを詰め込む「静的ページ抽出」の実装を解説します。