CW やランサーズで「◯◯サイトの情報を CSV で欲しい」という案件は多い。1件だけなら適当に書いても終わるが、月に何件も回すと、案件ごとにスクレイパーを書き直していることに気づく。
同じような URL 一覧 → データ抽出 → CSV 出力を、案件のたびに書き直していると、時間だけが溶けていく。この記事では 再利用可能な Python スクレイピング雛形の設計判断 を、実物ベースでまとめる。
スクレイピング案件のよくある流れ
案件はだいたいこの4段階で回る。
- 対象サイトから URL 一覧を取得(or クライアントから受領)
- 各 URL にアクセスして HTML を取得
- HTML から必要な項目を抽出(商品名 / 価格 / 在庫 等)
- CSV / スプレッドシート形式で整形して納品
このうち、案件ごとに変わるのは 1 (URL 一覧の出所) と 3 (抽出セレクタ) だけ。2 と 4 は毎回同じ処理なので、ここを雛形化すれば書き直す部分を最小化できる。
再利用テンプレの設計判断(5つ)
1. セレクタと URL リストは外部ファイル化
コード内にセレクタや対象 URL を埋め込むと、案件ごとに .py ファイルを丸ごと分岐することになる。以下のように分離する。
# config.yaml
target:
urls_file: input/urls.txt
selectors:
title: "h1.product-title"
price: "span.price"
stock: "div.stock-info"
output:
csv: output/result.csv
.py 側は「セレクタが何であっても」動く形にしておく。案件が変わったら YAML だけ差し替え で対応できる。
2. 取得 → パース → 整形 → CSV の4段階に分ける
処理を1つの関数に詰め込むと、途中でエラーが出た時にどの段階で失敗したか分からない。段階を分離する。
def fetch(url: str) -> str: # HTML 取得
...
def parse(html: str, selectors: dict) -> dict: # 必要項目抽出
...
def normalize(rows: list[dict]) -> list[dict]: # 型統一・空欄補完
...
def write_csv(rows: list[dict], path: str) -> None: # CSV 出力
...
段階を分けると、失敗した URL だけ再取得したり、抽出だけ手直しして再パースしたりが可能になる。時間短縮の本体は「失敗の局所化」。
3. リトライ + タイムアウト + User-Agent の3点セットは必須
対象サイトの負荷や一時的なネットワーク不調で、1回のリクエストが失敗するのは普通。素の requests.get(url) だけで書くと、100件中1件の失敗で全体が止まる。
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
retry = Retry(total=3, backoff_factor=1.0, status_forcelist=[429, 500, 502, 503, 504])
session.mount("https://", HTTPAdapter(max_retries=retry))
session.headers.update({"User-Agent": "MyBot/1.0 (contact: [email protected])"})
resp = session.get(url, timeout=15)
- retry: 3回まで指数バックオフでリトライ
- timeout: 15秒で見切りをつける
- User-Agent: 連絡先付きで対象サイト管理者に「誰の bot か」を明示
この3点で、100件中1件失敗しただけで全部止まる事故は防げる。
4. 対象サイトの規約と robots.txt を確認
スクレイピング案件を受けるときに、必ず最初にやる べきこと。
- 対象サイトの利用規約でスクレイピング禁止条項がないか
https://対象サイト/robots.txtでDisallowにヒットしていないか- API が公開されていないか(あれば API 優先)
- クローリング頻度を過度に上げない(1〜3秒 間隔を目安)
規約違反のスクレイピングは案件として受託しない。これを最初に断らないと、後で法的トラブルになる。
5. サンプルデータで dry-run
本番の URL 一覧(数百件以上あることも)でいきなり実行すると、途中で失敗したときに損害が大きい。先に3〜5件だけで通しで動かす。
if __name__ == "__main__":
import sys
dry_run = "--dry-run" in sys.argv
urls = load_urls(config["target"]["urls_file"])
if dry_run:
urls = urls[:5] # 先頭5件のみ
for url in urls:
html = fetch(url)
rows = parse(html, config["target"]["selectors"])
...
--dry-run オプションで先頭5件だけ処理して、CSV の出力形式や抽出結果を目視確認 → 本番実行、が事故を減らす王道。
無料版と有償版の違い
無料版テンプレ(メール登録で即DL、15KB):
- 最小構成の
.pyスクリプト - 使い方 PDF(10行程度)
- 動作サンプル用の URL 3件付き
有償版 (¥1,980 note販売中):
config.yaml分離済みの雛形- 4段階分離実装(fetch / parse / normalize / write_csv)
- リトライ + タイムアウト + User-Agent 3点セット
--dry-runフラグ実装済み- カスタマイズ手順書 PDF(セレクタの差し替えだけで別サイトに転用可能)
まず無料版で「動く手触り」を確認 → 有償版で「案件で回せる型」を得る、という段階設計。
「うちの案件で使いたい」「代行して欲しい」方へ
「対象サイトが決まっているが、Python も未経験」「毎回外注しているが、テンプレ化したい」方向けに、対応可能業務はこう。
対応:
- URL 一覧 → 情報抽出 → CSV 納品
- ページネーション込みの一括収集
- スプレッドシート直書き出し(GAS 連携)
- 定時実行(cron / launchd / GitHub Actions)
- リトライ・タイムアウト・エラー通知込み
対応外:
- 対象サイトの規約違反スクレイピング
- 認証必須ページの scraping bypass
- 大規模並列(1000並列など)
- CAPTCHA 突破
見積目安:
- URL 一覧 → CSV 出力(100〜500件): ¥3〜7万 / 3〜7日
- ページネーション + 複数サイト対応: ¥7〜15万 / 3〜10日
17項目の相談フォーム → 即日見積 → 動くコードを納品まで、Zoom不要・テキストのみで完結。売買推奨・投資助言・利益保証は行いません。
- 無料版DL: /ja/free/#tpl-scraping_starter
- 有償版 (note): スクレイピング雛形 ¥1,980
- 商品詳細: /ja/works/scraping-template/
- カスタム相談: /ja/request/
同じ設計思想で、あなたの案件の情報収集も再利用可能な雛形に落とし込みます。