Python学習およびポートフォリオ作成を目的として開発した、GUIベースのマルチドメインWebサイト解析・評価システムです。
実務における「非同期並行処理(マルチスレッド環境におけるデータ競合の防止)」「堅牢なクローリングにおける防御機構の突破」「値オブジェクトの設計思想を取り入れた状態管理」など、実践的なバックエンド・アーキテクチャを体系的に学ぶことを目的として開発しました。
指定されたExcelリスト(B列にドメイン名が配置されたシート)から、複数ドメインの SSL対応状況(常時SSL判定を含む)、サイト構成(主要CMSの多角的な検出)、総ページ数 を自動的にクローリングし、画面から定義したカスタムしきい値に基づきビジネス評価(◯, ×, 要確認)を自動付与するWebアプリケーションです。
単にデータを集めるスクレイパーにとどまらず、「サーバー負荷を最小化するクロールレート制御」「Cloudflareや各種クローラーブロック(403/503エラー)を回避するフェイクヘッダー」「HTTPリダイレクト追跡とHTTPS個別検証を組み合わせた2段構えのSSL監査機構」を独自実装。
フロントエンドには Streamlit を採用し、st.rerun() とバックグラウンドスレッドを協調させたポーリング機構により、1%刻みの進行状況を一切フリーズすることなく滑らかに描画するリアルタイム監視UIを実現しています。
-
バックグラウンド並行クローリング(ノンブロッキング&スレッドセーフ設計)
-
threadingを用いたバックグラウンドスレッドへの重いクローリング処理の完全委譲。 -
排他制御(
threading.Lock)を用いて、バックグラウンドでの解析結果の書き込みをアトミック(一括)に実行。Streamlit側の読込スレッドとのデータ競合や表示の不整合を完全に防止。 -
重いネットワークI/O処理中も Streamlit の描画メインスレッドを100%解放し、画面フリーズを排除。
-
インテリジェントなクローラー防御回避とSSL監査機構
-
スマートSSL&リダイレクト検証: 初回アクセスは
http://で行い、WAF(Web Application Firewall)やサーバーによるhttps://への自動リダイレクトの有無を追跡することで、「常時SSL(E列)」の判定基準であるリダイレクト処理を正確に検証。リダイレクトされない環境であっても個別にhttps://接続を並行検証する柔軟な設計。 -
接続不能時の安全なフォールバック: DNSエラーやボット拒否(403/401ブロック)、タイムアウト等の例外発生時もシステムをクラッシュさせず判定不能として安全にキャッチ。巡回フェーズへ「ページ数 0」として結果を引き継ぎ、最終結果を最優先で『要確認』に分類する堅牢性を担保。
-
ブラウザ欺瞞(User-Agent)と通信偽装: プレーンなPythonスクレイパーを即座にブロックする防御壁を突破するため、最新のWebブラウザ(Chrome/Safari等)のヘッダー情報を模倣。
-
主要CMSおよびサイト構成の高精度な動的検出
-
静的なHTML構文解析だけでなく、
wp-content/wp-includes資産などのHTMLソース内のシグネチャから、WordPress、Movable Type、EC-CUBE、Shopifyなどの国内主要CMSを多角的に判定。非CMSサイトは「なし」と自動識別。 -
セッションステートを用いた堅牢なリアルタイムUI
-
Streamlitのステートフル(
st.session_state)な設計。 -
while Trueによるブロッキングループを排除し、st.rerun()とバックグラウンドキューによる「能動的非同期ポーリング」を採用することで、進捗表示とメトリクスカードをリアルタイム更新。 -
Mypy Strict適合を意識したモデル設計と型安全性の徹底
-
ドメインモデル
ScrapingJobのプロパティをイミュータブル(Read-only)に設計し、スレッドセーフな状態管理を強制。状態の書き換えが必要な場合は、新しいインスタンスを再生成する「値オブジェクト」の設計思想を徹底。 -
SiteAssessmentモデル内の数値を扱うフィールド(ページ数、階層数)の型定義をint | Noneに厳密化。画面表示のための文字列表現(例: 100ページ以上を"100~"とする処理)はExcel出力の直前まで遅延させることで、ビジネスロジック内でのMypyエラーを排除し型安全性を確立。
| 分類 | 技術 |
|---|---|
| Language | Python 3.12+ |
| Package Management | uv |
| Web UI Framework | Streamlit (Custom Flat UI with CSS styling) |
| Scraping & Parsing | HTTPX / Requests, BeautifulSoup4 |
| Data Processing | OpenPyXL (Excel import / export, 元の行順維持マージ) |
| Testing | Pytest |
| Linter & Formatter | Ruff |
| Type Check | Mypy (Strict仕様適合) |
| CI/CD | GitHub Actions |
PYTHON-WEB-ANALYZER/
├── docs/ # ドキュメント関連ファイル(要件定義書等)
├── src/
│ └── web_analyzer/ # アプリケーションソースコード
│ ├── core/ # コアロジック
│ │ ├── crawler.py # クローラー(Web探索・取得)
│ │ ├── evaluator.py # 評価・判定ロジック
│ │ ├── excel_service.py # Excel出力・フォーマット調整
│ │ ├── scraper_service.py # スクレイピング(テキスト抽出・排他制御管理)
│ │ └── ssl_checker.py # SSL/TLS証明書・リダイレクト検証
│ ├── utils/ # 共通ユーティリティ関数
│ ├── __init__.py
│ ├── main.py # アプリケーションのエントリーポイント(Streamlit UI)
│ └── models.py # データモデル定義(ScrapingJob / SiteAssessment)
├── temp/ # 一時ファイル出力用ディレクトリ
├── tests/ # ユニットテスト
│ ├── test_evaluator.py # 評価ロジックのテスト
│ ├── test_excel_service.py # Excel出力のテスト
│ └── test_ssl_checker.py # SSL検証のテスト
├── .gitignore
├── .python-version
├── LICENSE # MITライセンス
├── pyproject.toml # プロジェクト設定・依存関係定義
├── README.md # プロジェクト概要・評価者向け説明書
└── uv.lock # uvロックファイル(厳密なバージョンロック)
- Python 3.12以上
- uv (一貫した開発・実行環境を再現するため必須)
uv がインストールされていない場合は以下を実行してください。
pip install uv
uv を用いて、配布環境や開発環境でのバージョンズレによるバグを100%防止し、一貫した実行環境を再現します。
git clone <repository-url>
cd PYTHON-WEB-ANALYZER
# uv を用いて lock ファイルに記録された依存関係を完全に同期 (自動で仮想環境が作成されます)
uv sync
uv run streamlit run src/web_analyzer/main.py
uv run pytest
uv run ruff check .
uv run ruff format .
uv run mypy src tests
GitHub Actionsを利用したCIパイプラインを構築しています。
ジョブを以下の2段階に分離し、静的解析(Lint/Type Check)に成功した場合のみテストを実行する構成としています。
- Ruff
- Mypy
- Pytest
test:
needs: lint
上記により、Lintエラーが発生した場合は不要なテスト実行をスキップし、CIの実行リソースを節約します。
堅牢性を担保するため、pytest を用いたコアロジックの単体テストを徹底しています。
- しきい値評価の妥当性テスト:指定されたカスタムしきい値(threshold_1, 2, 3)に基づいて、◎, ◯, △, × の判定が正確にマッピングされるかのマトリクステスト。
- 保留・却下理由の自動生成検証:接続失敗時(ページ数0)やページ数極小(1〜2ページ)の際に最優先で『要確認』となる挙動、および大規模サイトや会員ログイン画面を検出した際に、評価結果に応じた適切な理由テキストが自動生成されるかの仕様検証。
- 元の行順維持と双方向保証:インポートされたExcelシートの行順・構造を完全に維持したまま、解析結果の日付(M/D形式)や各ステータスをマージして出力できるかのI/Oテスト。また、100ページ以上のデータがExcel出力時に安全に
"100~"文字列に変換されるかの配置・変換ロジック検証。
- SSL接続・リダイレクト検証の正常性:初期接続パラメーター(最大10秒のリクエストタイムアウト設定)の妥当性、および正常なHTTPS通信から例外発生時(判定不能時の
None, None返却)にいたるまでのハンドリング検証。
Streamlitは「イベントや状態変化のたびに全コードが先頭から再実行される」という特殊なライフサイクルを持っています。そのため、重い処理をバックグラウンドに逃がすだけでなく、メインスレッドがポーリングでデータを読み出す瞬間に、バックグラウンド側がデータを中途半端に書き換えてしまうとUIの崩れや誤判定(競合状態)が発生します。
本システムでは、threading.Lock を導入してデータモデルの全プロパティの書き換えを一括(アトミック)で実行するスレッドセーフな同期デザインを習得しました。
商用Webサイトの解析では、セキュリティフィルター(WAF等)による拒否や、サーバー独自のプロトコル制限に直面します。
本システムの開発を通じ、適切なUser-Agent偽装、接続リクエストごとのタイムアウト制限、および http:// からのリダイレクト追跡と個別HTTPS検証を組み合わせることで、エラーでスタックすることなく安全に結果を持ち帰る「フォールバック前提のクライアント設計」を習得しました。
状態変更が多発する並行処理システムにおいて、データ型の曖昧さはバグの最大の原因になります。 本システムでは、ジョブの状態変化時に新しいインスタンスを再生成するイミュータブル(不変)アプローチと、データの保持には純粋な数値型を用いつつ表示用変換を出力層まで遅延させるアプローチを採用しました。これにより、Mypyの厳格な型チェックをパスし、リファクタリング耐性の極めて高い堅牢なプログラム構造を実現するスキルを習得しました。
MIT License
