月間およそ4億5,000万回のアクセスがあり、560万人のセラーが1億件を超える商品を出品しているEtsyには、価格、トレンド、レビュー、競合動向に関する公開情報が蓄積されています。これらを一件ずつ確認して表へ転記するには、大きな工数がかかります。
私自身、ある市場調査で競合の商品リストを手入力した経験があります。30件ほど入力した時点で、収集作業に時間を取られ、分析に使える時間が少なくなる課題を感じました。一方、価格分析、商品開発、ニッチの探索、セラー比較では、Etsyのデータを判断材料として活用できます。本記事では、検索結果・商品・ショップ・レビューという4つのページタイプを対象に、PythonでEtsyデータを収集する手順を順番に解説します。あわせて、Etsyのボット対策を踏まえた運用上の注意点と、スクリプトを書かずに進めるノーコードの選択肢も取り上げます。
PythonによるEtsyスクレイピングの仕組み
ウェブスクレイピングとは、ページへ自動的にアクセスし、商品名、価格、説明、画像、評価、レビューなどの必要な情報を抽出して、スプレッドシートやデータベースで扱える形に整える処理です。手作業による収集をコードで自動化します。
この用途で広く使われている言語の一つがPythonです。Stack Overflowの年次調査では毎年のように人気上位3位に入り、PyPIでもスクレイピング関連ライブラリがダウンロード数の上位に並びます。初心者でも書き始めやすく、コミュニティが大きいうえ、用途別のライブラリが揃っているためです。代表例には、ページを取得するRequests、HTMLを解析するBeautifulSoup、ブラウザを操作するSeleniumやPlaywright、データを整形・出力するpandasがあります。
Etsyを対象にする場合は、ブラウザに描画されるHTMLや、ページ内のJSONから値を取得します。主に抽出できる情報は次のとおりです。
- 商品名、価格、説明、画像、バリエーション
- セラー/ショップ情報(名前、販売数、所在地、評価)
- 評価とレビュー全文
- 検索結果一覧、カテゴリ、トレンドの兆候
Etsyデータを活用できる主な業務
整形したEtsyデータは、価格調整、商品企画、キーワード調査、競合分析などの判断材料として利用できます。必要なデータと期待できる効果は、担当業務や分析条件によって異なります。

| ユースケース | スクレイピング対象 | 恩恵を受ける人 | ビジネスへの影響 |
|---|---|---|---|
| 競合価格分析 | 検索結果 + 商品価格 | EC運用、セラー | 動的価格設定により平均で収益が5〜22%向上する可能性 |
| ニッチ・トレンド発掘 | 検索結果、トレンド商品一覧 | 創業者、アナリスト | トレンドのニッチをいち早く発見(例:「preppy pajamas」は検索数が+1,112%増加) |
| 商品開発・改善 | レビュー、商品詳細 | プロダクトチーム | あるキッチン用品ブランドはレビュー感情データを活用し、60日で「ベストセラー1位」を奪還 |
| SEO・キーワード調査 | 検索結果、商品タイトル/タグ | マーケティングチーム | 需要が高く、競争の少ないキーワードを特定 |
| セラー比較 | ショップページ、販売数 | 営業チーム、アナリスト | 購入リストではなく、1件あたり$0.01〜0.10で有望なリードリストを構築 |
| 在庫・在庫切れ監視 | 商品の在庫状況 | EC運用 | 競合の在庫変化に素早く対応 |
用途によって必要なページタイプが異なるため、本チュートリアルでは検索結果、商品、ショップ、レビューの4種類を順に扱います。
時間短縮効果:手作業と自動化の比較
- 手作業でのEtsy調査: 1商品あたり30〜45分(100商品なら50〜75時間)
- 自動スクレイピング: 100件を2〜5分で取得
- AIによるスクレイピングは30〜40%高速で、精度は最大99.5%
Etsy APIとウェブスクレイピング:どちらを選ぶべきか?
コードを書き始める前に、Etsy公式APIを利用するのか、サイト上の公開ページから直接データを取得するのかを決めます。フォーラムでも頻繁に取り上げられる論点ですが、選択は必要なデータによって変わります。
Etsy APIでできること、できないこと
EtsyはOAuth 2.0で認証するAPI v3を提供しています。自分のショップの出品・注文・領収書を取得する用途では利用できますが、用途によっては次の制約があります。
- 競合データ: 取得できるのは原則として自分のショップです。他のセラーの価格、販売数、出品状況は対象外です。
- レビュー: レビュー本文を大量に取得するためのエンドポイントは用意されていません。
- レート制限: 標準で毎秒10リクエスト、1日あたり10,000リクエスト。オフセットの上限は12,000件です。
- AI/ML利用: アプリ審査では利用目的に関する制約があります。
- ドキュメント: 例の少なさ、廃止済みエンドポイントの記載、サポート速度について、コミュニティから指摘があります。
ウェブスクレイピングのほうが適している場面
ショップを横断した分析、レビューの感情分析、競合調査、APIで提供されない公開データの取得が必要な場合は、ウェブスクレイピングが選択肢になります。一方で、Etsyのボット対策への対応や、取得環境の構築・保守が必要です。対象データと運用規模を整理したうえで、APIやノーコード方式と比較します。
比較表:API vs. スクレイピング vs. ノーコード
選択時は、必要なデータ、認証、ボット対策、初期設定にかけられる時間を比較します。
| 比較項目 | Etsy公式API | Pythonによるウェブスクレイピング | Thunderbit(ノーコード) |
|---|---|---|---|
| 商品価格へのアクセス | ✅(一部フィールドのみ) | ✅ HTML/JSON-LDから取得 | ✅ AIが可視フィールドを抽出 |
| レビューデータ | ❌ 一括取得不可 | ✅ レビュー用エンドポイント/HTML経由 | ✅ サブページスクレイピング |
| 競合ショップデータ | ❌ 自分のショップのみ | ✅ 公開ショップを取得対象にできる | ✅ 公開ショップを取得対象にできる |
| 認証の必要性 | ✅ OAuth 2.0 | ⚠️ ログイン済みデータはCookieが必要 | ⚠️ ログイン時はブラウザスクレイピング |
| ボット対策リスク | 低い(API利用条件への対応は必要) | 高い(DataDome) | ブラウザセッションを利用(対象条件による) |
| 初期設定時間 | 中程度(APIキー、OAuth) | 長い(コード + プロキシ) | 約2分(利用条件による) |
自分のショップデータを扱う場合は公式APIが候補です。ショップ横断の分析やレビュー、競合の公開データが必要な場合は、Pythonまたはノーコード方式を、保守負荷も含めて比較します。
コードを書く前に、Pythonでのスクレイピング手法を選ぶ
Requests + BeautifulSoup、Selenium、プロキシAPI、ノーコードツールには、それぞれ適した用途があります。習熟度、予算、対象ページ、必要な運用規模を基準に選びます。費用は米ドル表記で、サービスのプランや利用量によって変わります。
| 手法 | 向いている用途 | 学習コスト | JS対応 | ボット対策 | コスト |
|---|---|---|---|---|---|
| Requests + BeautifulSoup | 挙動を細かく制御したい開発者 | 中 | ❌ | 手動対応(ヘッダー、プロキシ) | 無料 + プロキシ費用 |
| Selenium / Playwright | JS中心のページ、ログインフロー | 高 | ✅ | 一部対応(ブラウザ指紋) | 無料 + プロキシ費用 |
| プロキシAPIサービス | 大規模運用 + ボット対策への対応 | 中 | ✅(API経由) | ✅ サービス側で対策機能を提供 | 月額$49〜 |
| Thunderbit(ノーコード) | 非エンジニア、手早い抽出 | 非常に低い | ✅(ブラウザネイティブ) | ✅(ブラウザセッションを利用) | 無料プランあり |
取得処理を細かく制御し、自社システムへ組み込む場合はRequests + BeautifulSoupが候補です。JavaScript描画やログイン操作が必要なら、SeleniumやPlaywrightを検討します。大規模運用では、プロキシAPIを含めた保守体制が必要です。コードの実装・保守を避け、まず小規模に抽出したい場合はThunderbitが候補になります。
EtsyのDataDomeによるボット対策を理解する
Etsyでは、プロキシの追加だけで安定して取得できるとは限りません。Etsyが採用しているボット対策システムがDataDomeです。^DataDomeの事例紹介ではEtsyが成功事例として紹介され、かつてスクレイパーがEtsyの計算コストの約1%を占めていたと記載されています。

DataDomeとは何か、どう動くのか?
DataDomeはIPアドレスだけでなく、複数の信号を組み合わせてアクセスを判定します。
- TLSフィンガープリント(JA3): Pythonの
requestsには固有のTLS署名があり、判定材料になる場合があります。 - HTTPヘッダー/プロトコル検査: ブラウザの通信としてヘッダーが揃い、内容や順序に整合性があるかを検査します。
- JavaScriptフィンガープリント(Picasso protocol): ブラウザ上でJSチャレンジを実行し、利用環境を判定します。
- 行動ベースの機械学習: 1リクエストにつき35を超えるシグナルを読み、サイトごとに85,000以上のモデルを使用しています。
- IPレピュテーションスコアリング: データセンターのIPはリスクが高いと判定される場合があります。
- Cookie検証:
datadomeCookieの有無と有効性を検査します。
ブロックされたサイン(確認方法も含む)
注意が必要なのは、200 OKが返っていても、レスポンス本文がCAPTCHAページになっている場合です。ほかにも次の兆候があります。
- 403 Forbidden エラー
- リダイレクトループ
- レスポンス本文に
ddJavaScriptオブジェクトやスライダー型CAPTCHAのHTMLが含まれる
ステータスコードだけで成功と判断せず、レスポンス本文が想定したデータかを検証します。簡単な判定例は次のとおりです。
if "captcha" in resp.text.lower() or "datadome" in resp.text.lower():
print("ブロックされました。データの代わりにCAPTCHAページが返っています。")
検知を減らすためのヘッダーとCookie
ブロックを完全に防ぐ方法はありません。ヘッダーとCookieの整合性を保つことは通信エラーを減らす一助になりますが、アクセス許可や取得成功を保証するものではありません。
session = requests.Session()
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/133.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"Sec-Ch-Ua": '"Chromium";v="133", "Not-A.Brand";v="99", "Google Chrome";v="133"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Windows"',
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Upgrade-Insecure-Requests": "1",
})
あわせて、次の点を管理します。
requests.Session()を使い、リクエスト間でCookieを維持する。- 1回ごとの間に2〜7秒のランダムな間隔を置く。
- 参照元の流れを保つ。ホーム、検索、商品ページの順に移動する。
- 規模を上げる場合は、対象サイトの条件とアクセス頻度を見直し、必要に応じて住宅回線プロキシのローテーションを検討する。データセンターのIPは検知対象になりやすい場合があります。
これらの設定を行っても、検知を完全に避けられるわけではありません。実行前にEtsyの利用規約と取得範囲を照合し、大規模運用では公式API、プロキシサービス、ブラウザベースの方法を保守負荷も含めて比較します。
EtsyをスクレイピングするためのPython環境を整える
取りかかる前の前提です。
- 難易度: 中級
- 所要時間: 約30〜60分(セットアップ + 初回スクレイピング)
- 必要なもの: Python 3.8以上、pip、コードエディタ、Chromeブラウザ(DevTools確認用)
依存関係をインストールする
作業用フォルダを作り、仮想環境を立てて、必要なライブラリを入れます。
mkdir etsy-scraper && cd etsy-scraper
python -m venv venv
source venv/bin/activate # Windowsの場合: venv\Scripts\activate
pip install requests beautifulsoup4 lxml pandas
- requests — ウェブページを取得
- beautifulsoup4 — HTMLを解析
- lxml — 高速なHTMLパーサー(任意だが推奨)
- pandas — データをCSV/Excel向けに整形・出力
のちのちログインやJS中心のページでブラウザ自動化が要る場面が出てきたら、これも足しておきます。
pip install selenium
コードを書く前にEtsyのページ構造を理解する
Etsyの多くの商品ページでは、<script type="application/ld+json"> タグ内に構造化データが含まれています。JSON-LDには商品名、価格、評価、画像などが整理された形で入っているため、変更の影響を受けやすいCSSセレクターを項目ごとに設定する前に確認すると効率的です。
Etsyの商品ページを開き、右クリックから「ページのソースを表示」を選び、application/ld+json を検索します。商品情報は @type: Product、検索結果ページでは @type: ItemList のブロックを探します。
配送情報やレビュー本文など、JSON-LDに含まれないデータはCSSセレクターで補います。まずJSON-LDの内容を確認し、不足する項目だけHTMLから取得する順序にすると保守しやすくなります。
ステップ1:PythonでEtsyの検索結果をスクレイピングする
ニッチの定点観測、競合価格の追跡、商品データベースの作成では、検索結果ページが商品URLと基本情報を集める起点になります。
検索URLを作る
Etsyの検索URLは次の形式です。
https://www.etsy.com/search?q={keyword}&ref=pagination&page={page_number}
複数の語句を使う場合は、スペースをURLエンコードします(handmade+jewelry や handmade%20jewelry のように)。ref=pagination はページネーション時に付与される参照パラメータです。
ほかにも order(most_relevant, price_asc, price_desc, date_desc)、min_price、max_price、ship_to、free_shipping=true といったパラメータが使えます。返される件数は1ページあたり48件です。
リクエストを送ってHTMLを解析する
import requests
from bs4 import BeautifulSoup
import json
import time
import random
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
}
def scrape_etsy_search(query, max_pages=3):
all_products = []
for page in range(1, max_pages + 1):
url = f"https://www.etsy.com/search?q={query}&ref=pagination&page={page}"
resp = requests.get(url, headers=headers, timeout=30)
if "captcha" in resp.text.lower():
print(f"{page}ページ目でブロックされました。待機時間やプロキシの追加を試してください。")
break
soup = BeautifulSoup(resp.text, "lxml")
for script in soup.find_all("script", type="application/ld+json"):
data = json.loads(script.string)
if data.get("@type") == "ItemList":
for item in data.get("itemListElement", []):
all_products.append({
"name": item.get("name"),
"url": item.get("url"),
"image": item.get("image"),
"price": item.get("offers", {}).get("price"),
"currency": item.get("offers", {}).get("priceCurrency"),
"position": item.get("position"),
})
time.sleep(random.uniform(2, 5))
return all_products
JSON-LDから出品データを抽出する
各出品の名前・URL・画像・価格・通貨は、itemListElement の配列にまとまって入っています。星評価や件数のようにJSON-LDから抜け落ちている値が欲しいときは、CSSセレクターに切り替えて拾いましょう。
- 出品カード:
.v2-listing-card - タイトル:
h3.v2-listing-card__title - 価格:
span.currency-value - リンク:
a.listing-link(href)
ページネーションを処理する
ページを順に取得し、リクエスト間にはランダムな待機時間を設定します。Etsyが返すページ数はクエリによって異なり、おおむね20〜250ページの範囲です。
results = scrape_etsy_search("handmade+jewelry", max_pages=5)
print(f"{len(results)}件をスクレイピングしました。")
私の環境では、5ページ分の取得に約20秒かかりました。同じデータを手作業で転記した場合は約30分かかったため、反復調査では処理時間を短縮できます。
ステップ2:PythonでEtsyの商品ページをスクレイピングする
検索結果から商品URLの一覧を取得したら、各商品ページを開き、詳細データを抽出します。
商品ページを取得する
def scrape_etsy_product(url):
resp = requests.get(url, headers=headers, timeout=30)
soup = BeautifulSoup(resp.text, "lxml")
for script in soup.find_all("script", type="application/ld+json"):
data = json.loads(script.string)
if data.get("@type") == "Product":
offers = data.get("offers", {})
price = offers.get("price") or offers.get("lowPrice")
rating_data = data.get("aggregateRating", {})
return {
"name": data.get("name"),
"description": data.get("description", "")[:500],
"brand": data.get("brand", {}).get("name") if isinstance(data.get("brand"), dict) else data.get("brand"),
"category": data.get("category"),
"price": price,
"currency": offers.get("priceCurrency"),
"availability": offers.get("availability"),
"rating": rating_data.get("ratingValue"),
"review_count": rating_data.get("reviewCount"),
"images": data.get("image", []),
"sku": data.get("sku"),
"material": data.get("material"),
}
return None
価格のバリエーションを扱う
offers.price に単一価格が入る商品があります。一方、サイズや色などのバリエーションを持つ商品では、offers.lowPrice と offers.highPrice が使われる場合があります。上のコードは price が空の場合に lowPrice を取得するため、単一価格または最低価格を保存できます。価格帯全体が必要な場合は、highPrice も取得項目に追加します。
CSSセレクターで追加フィールドを取得する
配送情報、バリエーション、セラーの詳細など、JSON-LDに含まれないデータはCSSセレクターで補います。
- タイトル:
h1[data-buy-box-listing-title] - バリエーション:
select[data-selector-id]またはdiv[data-option-set] - 配送情報: 配送セクション付近の
div.wt-text-caption
JSON-LDは構造が比較的安定している一方、取得できる項目が限られます。CSSセレクターは取得範囲を広げられますが、レイアウト変更の影響を受けやすいため、保守が必要です。
ステップ3:PythonでEtsyのショップページをスクレイピングする
ショップページには、販売数、所在地、評価、出品一覧など、営業リスト作成や競合分析に使える情報があります。このステップでは、商品ページとは異なるショップ単位の項目を取得します。
ショップURLを作ってページを取得する
def scrape_etsy_shop(shop_name):
url = f"https://www.etsy.com/shop/{shop_name}"
resp = requests.get(url, headers=headers, timeout=30)
soup = BeautifulSoup(resp.text, "lxml")
# HTMLからショップメタデータを取得(JSON-LDにはない)
sales_el = soup.select_one("div.shop-sales-reviews a")
rating_el = soup.find("input", {"name": "initial-rating"})
location_el = soup.select_one("div.shop-location")
shop_data = {
"name": shop_name,
"sales": sales_el.text.strip() if sales_el else None,
"rating": rating_el["value"] if rating_el else None,
"location": location_el.text.strip() if location_el else None,
}
# JSON-LDから出品一覧を取得
listings = []
for script in soup.find_all("script", type="application/ld+json"):
data = json.loads(script.string)
if data.get("@type") == "ItemList":
for item in data.get("itemListElement", []):
listings.append({
"name": item.get("name"),
"url": item.get("url"),
"price": item.get("offers", {}).get("price"),
})
shop_data["listings"] = listings
return shop_data
ショップページから取得できるもの
ショップページのJSON-LDは @type: ItemList で出品の一覧こそ押さえてくれますが、販売数・所在地・評価といったショップ全体のメタデータまでは含みません。そこを取りにいくにはCSSセレクターの力が要ります。
| データ項目 | セレクター | 補足 |
|---|---|---|
| ショップ名 | h1 またはメタタイトル | 通常はページタイトル内 |
| 総販売数 | div.shop-sales-reviews a | 「12,345 sales」のようなテキスト |
| 星評価 | input[name="initial-rating"] の value | 1〜5の数値 |
| 所在地 | div.shop-location | 都市、国 |
| 開店時期 | div.shop-info | 日付テキスト |
ショップデータが効くのは、リードリストづくり、競合との比較、そして特定ニッチのトップセラーを見つけ出す場面です。
ステップ4:PythonでEtsyのレビューをスクレイピングする
Etsyのレビューは、商品改善や顧客理解に役立つ一方、取得方法が商品情報とは異なります。本文、評価、日付は最初のHTMLに含まれず、内部API経由で後から読み込まれます。
方法1:Etsy内部のレビューAPIエンドポイントを見つける
商品ページをChromeで開き、DevTools(F12)を立ち上げて、Networkタブを見ながらレビューの欄までスクロールしてみてください。すると、こんなPOSTリクエストが姿を現します。
https://www.etsy.com/api/v3/ajax/bespoke/member/neu/specs/deep_dive_reviews
このエンドポイントは、レビューカードを含んだHTMLの断片を返します。呼び出すには、次の3つが要ります。
- listing_id — 商品URLに含まれる数値ID
- shop_id — 商品ページのHTMLから正規表現で抜く
- csrf_nonce — ページ内の
<meta>タグから抜く
IDとCSRFトークンを抽出する
import re
def get_review_params(product_url):
resp = requests.get(product_url, headers=headers)
html = resp.text
listing_id = product_url.split("/")[-1].split("?")[0]
shop_id_match = re.search(r'"shopId"\s*:\s*(\d+)', html)
shop_id = shop_id_match.group(1) if shop_id_match else None
soup = BeautifulSoup(html, "lxml")
csrf_meta = soup.find("meta", {"name": "csrf_nonce"})
csrf = csrf_meta["content"] if csrf_meta else None
return listing_id, shop_id, csrf
ページネーション付きでレビューをスクレイピングする
def scrape_reviews(listing_id, shop_id, csrf, max_pages=5):
session = requests.Session()
session.headers.update(headers)
all_reviews = []
for page in range(1, max_pages + 1):
payload = {
"specs": {
"deep_dive_reviews": {
"module_path": "neu/specs/deep_dive_reviews",
"listing_id": listing_id,
"shop_id": shop_id,
"page": page,
}
}
}
resp = session.post(
"https://www.etsy.com/api/v3/ajax/bespoke/member/neu/specs/deep_dive_reviews",
json=payload,
headers={"x-csrf-token": csrf, "Content-Type": "application/json"},
)
data = resp.json()
html_fragment = data.get("output", {}).get("deep_dive_reviews", "")
review_soup = BeautifulSoup(html_fragment, "lxml")
for card in review_soup.select("div.review-card"):
rating_el = card.find("input", {"name": "rating"})
text_el = card.select_one("div.wt-text-body")
user_el = card.select_one("a[data-review-username]")
date_el = card.select_one("p.wt-text-body-small")
all_reviews.append({
"rating": rating_el["value"] if rating_el else None,
"text": text_el.text.strip() if text_el else None,
"reviewer": user_el.text.strip() if user_el else None,
"date": date_el.text.strip() if date_el else None,
})
time.sleep(random.uniform(2, 5))
return all_reviews
方法2:HTMLからレビューを解析する(フォールバック)
CSRFトークンでつまずくなど、API方式がうまくいかないこともあります。その場合は、商品ページのHTMLから最初のレビューだけを直に読み取れます。ただし静的HTMLに載っているのは初回分に限られるので、それ以上欲しければAPIか、Seleniumのようなブラウザ自動化に頼ることになります。
ログイン必須データを扱う:自分のEtsyショップをスクレイピングする
注文、売上、統計など、自分のセラーダッシュボードにあるデータを取得する場合は、ログイン済みセッションを扱う必要があります。
requests 単体ではEtsyのダッシュボードへアクセスできません。認証済みセッションのCookieを保持していないためです。
方法1:Seleniumで手動ログインし、Cookieを取得する
Seleniumでブラウザを起こし、手動なり自動化なりでログインを通したあと、認証された状態のままスクレイピングを続けます。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.etsy.com/signin")
# ブラウザで手動ログインしたら、次を実行:
input("ログイン後にEnterを押してください...")
cookies = driver.get_cookies()
# 以後は driver.get() でダッシュボードページに移動してスクレイピング
SeleniumセッションのCookieを保存しておけば、初回ログインのあとは requests.Session() と合わせて使い回し、より速く軽い取得に切り替えることもできます。
方法2:ブラウザCookieをエクスポートしてRequestsで使う
「EditThisCookie」のようなブラウザ拡張を使うと、現在のEtsyセッションCookieを書き出し、Requestsのセッションへ読み込めます。
セッションCookieはログイン状態を再現できる認証情報です。自分のアカウントだけを対象にし、共有端末や公開リポジトリへ保存せず、作業後は不要なファイルを削除します。
import requests
session = requests.Session()
# ブラウザからエクスポートしたCookieを追加
session.cookies.set("uaid", "YOUR_UAID_VALUE", domain=".etsy.com")
session.cookies.set("user_prefs", "YOUR_USER_PREFS_VALUE", domain=".etsy.com")
# ...必要に応じて他のセッションCookieも追加
resp = session.get("https://www.etsy.com/your/orders", headers=headers)
ノーコードの選択肢:Thunderbitのブラウザスクレイピングモード
Thunderbit はChromeブラウザ内で動作するため、ログイン済みのEtsyセッションを利用できます。認証コードの処理やCookieの書き出しを別途実装せず、自分のEtsyダッシュボードで取得項目を設定できます。
注文、売上、統計など、自分のアカウントで閲覧権限のあるデータをスクリプトなしで取得したい場合の選択肢です。対象データの取り扱いとEtsyの利用条件を踏まえて使用します。
スクレイピングしたEtsyデータの保存と活用
CSVまたはJSONに保存する
import pandas as pd
df = pd.DataFrame(results)
df.to_csv("etsy_products.csv", index=False, encoding="utf-8")
df.to_json("etsy_products.json", orient="records", indent=2)
押さえておきたい定石は3つ。ファイル名にタイムスタンプを入れること、UTF-8で書き出すこと、そして商品名に紛れ込む特殊文字を丁寧に処理することです(Etsyのセラーは絵文字やアクセント付きの文字を好んで使います)。
Google Sheets、Airtable、Notionへ出力する
Pythonを使う場合は、gspread(Google Sheets向け)やAirtable APIなどを介して、コードからデータを出力できます。Thunderbit では、Google Sheets、Excel、Airtable、Notionへ画面操作で書き出せます。APIキーやOAuthを別途設定せずに使える設計で、エクスポートは無料です。
コードなしで進める:ThunderbitでEtsyをスクレイピングする方法(ノーコード代替)
Python環境、プロキシ、CSSセレクターを自分で構築・保守しない場合は、Thunderbit を使ってEtsyデータを取得する方法があります。ここでは、インストールから項目設定、抽出、出力までの流れを説明します。
ThunderbitのChrome拡張機能をインストールする
Chromeウェブストア を開いてThunderbitを入れてください。無料アカウントを作れば、無料枠で月6ページまで試せて、エクスポートはすべて無料です。
EtsyページでAIに抽出項目を提案させる
Etsyの検索ページ、商品ページ、ショップページのうち、取得対象のページを開きます。Thunderbitのサイドバーから 「AIで項目を提案」 をクリックすると、AIがページを読み取り、商品名、価格、評価、画像、ショップ名、タグ、配送情報などの列を提案します。用途に合わせて、提案された列を追加・削除・調整します。
スクレイピングしてエクスポートする
「スクレイプ」 を押すと、現在開いているページから設定済みの項目を抽出できます。結果が複数ページに分かれる場合は、Thunderbitのページネーションスクレイピングを使います。商品URLの一覧から各ページの説明、レビュー、配送情報を追加したい場合は、サブページスクレイピング を設定します。リンク先を順に開き、追加項目を元の一覧へ結合します。
書き出し先はExcel・Google Sheets・Airtable・Notion、いずれも無料です。
EtsyスクレイピングでThunderbitが向いている場面
- プロキシやボット対策コードを自分で実装したくない場合。 Chrome内で動作し、現在のブラウザセッションを利用できます。ただし、対象ページの利用条件やアクセス権限は別途考慮が必要です。
- レイアウト変更時の保守を減らしたい場合。 AIによる項目提案を使って抽出列を再設定できます。変更後は取得結果を検証します。
- 単発調査、競合分析、非エンジニアによる抽出。 独自のPython環境を構築する前に、小規模な取得を試したい場合に向いています。
- サブページスクレイピング を使うと、商品URLの一覧に詳細ページの項目を追加できます。
操作の様子は、ThunderbitのYouTubeチャンネル で確認できます。
Python vs. Thunderbit:6か月のコスト比較
以下は米ドル表記の試算です。対象件数、人件費、プロキシ利用量、プランによって結果が変わるため、自社条件に置き換えて比較します。
| 要素 | Pythonで自作 | Thunderbit |
|---|---|---|
| セットアップ時間 | 8〜20時間 | 5分以内(小規模な初期設定の例) |
| 6か月コスト(労務費・プロキシ込み) | $2,720〜9,450(試算条件による) | $90〜228(試算条件による) |
| 月次保守 | 4〜10時間以上(セレクター更新が80%以上の工数) | 0〜1時間(対象ページによる) |
| ボット対策対応 | 住宅回線プロキシを通常の85倍のクレジットコストで利用 | ブラウザセッションを利用(結果は対象条件による) |
| データ品質 | 高い(実装・検証次第) | 高い(抽出結果の検証が必要) |
独自ロジック、完全な制御、大規模パイプラインへの組み込みが必要な場合はPythonが向いています。単発または小規模な業務で、実装と保守の時間を抑えたい場合はノーコードが候補になります。費用だけでなく、必要な制御範囲と検証工数を含めて判断します。
Etsyスクレイピングの法的・倫理的な注意点
スクレイピングを行う際は、サイトの利用規約、アクセス方法、取得データの利用目的を分けて検討する必要があります。主な注意点は次のとおりです。
- Etsyの利用規約には、自動アクセスを制限する条項があります。 EtsyはDataDomeによる技術的防御も実施しています。スクレイパーを直接対象としたEtsy固有の訴訟は知られていませんが、規約上許可されることを意味するものではありません。
- 公開データだけを対象にすること。 認証を回避したり、自分のものではない非公開のセラーダッシュボードへアクセスしたりしてはいけません。
- アクセス頻度を抑えること。 本記事のコード例では1回ごとに2〜7秒空けていますが、この間隔が許可や安全性を保証するわけではありません。
robots.txtを参照すること。 Etsyは検索ページを許可し、一部のパスを制限していますが、内容は変更される可能性があります。- 個人データを責任を持って扱うこと。 GDPRをはじめ、用途と対象者に適用されるプライバシー法を考慮します。
- 商用規模のスクレイピングでは法務に相談すること。
背景を押さえたい場合は、ウェブスクレイピングの法的論点 が参考になります。Meta v. Bright Data(2024)は公開データのスクレイピングに関する判断ですが、すべてのサイトや取得方法へ同じ結論を適用できるわけではありません。
まとめ:重要ポイントのおさらい
本記事では、検索結果、商品、ショップ、レビューの順に、Etsyデータを取得する方法を説明しました。実装時の判断点は次のとおりです。
- EtsyのJSON-LD構造化データ は、商品名や価格などの基本項目を取得する起点になります。不足する項目はCSSセレクターで補います。
- DataDomeへの対応 では、ヘッダー、待機時間、Cookie、アクセス頻度を管理する必要があります。ただし、これらは取得成功や規約上の許可を保証しません。
- Etsy APIには取得範囲の制約があります。 自分のショップ以外の公開データやレビューが必要な場合は、スクレイピングを含む別の方法と比較します。
- Thunderbitはノーコードの選択肢 です。スクリプトの構築・保守を避けて小規模な取得を試したい場合に候補となります。独自処理や大規模連携にはPythonも比較対象です。
- Etsyの利用規約、データの公開範囲、個人情報、サーバー負荷を考慮して運用します。
コードを書かずに試す場合は、まず1ページを対象にThunderbitを無料で試してみてください。取得項目、精度、出力形式が用途に合うかを検証してから、ページ数や対象範囲を広げます。本記事のPythonコードを使う場合も、少ないページ数から始め、ログとエラー内容を記録すると保守しやすくなります。
さらに踏み込んだ解説は、Etsyスクレイパーを使って売上戦略を強化する方法 と おすすめのAIウェブスクレイパーまとめ もどうぞ。
ThunderbitでEtsyデータをより速くスクレイピング Get Started Free
よくある質問
1. PythonでEtsyをスクレイピングするのは合法ですか?
公開データのスクレイピングについては、Meta v. Bright DataやhiQ v. LinkedInなどの判例がありますが、対象サイト、取得方法、利用目的によって判断は異なります。Etsyの利用規約は自動アクセスを制限しているため、実行前に規約と robots.txt を照合してください。大規模利用や商用利用では、法務へ相談することをおすすめします。
2. ブロックされずにEtsyをスクレイピングできますか?
ブロックを完全に避けることはできません。ヘッダーの整合性、リクエスト間隔、Cookieの維持、アクセス量の管理は、エラーを減らすための要素です。住宅回線プロキシを使う場合も、取得成功や許可を保証するものではありません。ThunderbitはChromeセッション内で動作しますが、対象ページの条件と取得結果を検証する必要があります。
3. スクレイピングの代わりに使えるEtsyのAPIはありますか?
EtsyはAPI v3を提供しています。自分のショップのデータを扱う用途が中心で、レビューや競合ショップを横断した分析には制約があります。必要なデータ、認証、保守方法を整理し、APIとスクレイピングを比較します。
4. Etsyをスクレイピングするのに必要なPythonライブラリは何ですか?
最小構成は requests、beautifulsoup4、出力用の pandas、標準ライブラリの json です。JavaScriptで描画されるページやログインが必要なページでは selenium を追加します。HTML解析には lxml を利用できます。
5. Etsyのレビューだけを具体的にスクレイピングするにはどうすればいいですか?
Etsyのレビューは内部APIエンドポイント(/api/v3/ajax/bespoke/member/neu/specs/deep_dive_reviews)経由で読み込まれます。商品ページからlisting ID、shop ID、CSRFトークンを取得し、ページ番号を付けてエンドポイントへPOSTします。フォールバックとして、商品ページHTMLに含まれる最初のレビュー群を解析する方法もあります。本記事では両方の手順を説明しています。
さらに詳しく


