eBayの出品情報と売却データを価格調査のためにスクレイピングする方法

eBayの売却履歴は、自由市場の価格データベースに最も近いものです。これを解放する2つのURLパラメータを知っていればの話です。ここでは、出品情報、バリアント、実際の取引価格を大規模にスクレイピングする方法を紹介します。

eBayはウェブ上で最大のピアツーピアマーケットプレイスの一つであり、価格調査、競合追跡、再販評価のための金鉱です。公式の開発者SDKがありますが、最も有用なデータである実際に売れた商品の価格は、公開された検索ページから直接収集するのが最も簡単です。このガイドでは、eBayの出品情報、バリアントデータ、実際の売却価格をスクレイピングする方法と、最初の数百リクエストを超えてスクレイパーを存続させるプロキシ設定を紹介します。

検索URLはAPIです

eBayを検索すると、クエリはURLに完全にエンコードされ、いくつかのパラメータが返される内容を正確に制御します。この5つをマスターすれば、ブラウザに触れることなくプログラム的にeBayのカタログを操作できます。

並び順パラメータ_sopは注目に値します: その値は、新着、送料込みの最安値、または終了間近で結果を並べ替え、ターゲットフィードを形成します — 変化を監視するための新着リスト、ディールを見つけるための最安値。_sacatで制限することで、広範なキーワードを適切な部門に絞り込み、解析する前にノイズを取り除くことができます。キーワード、カテゴリ、並び順を組み合わせることで、ほとんどの調査クエリを単一のURLとして表現でき、これがeBayを自動化しやすくしている理由です。

import requests
from urllib.parse import urlencode

proxy = "http://USER:PASS@gate.quantumproxies.io:8000"
proxies = {"http": proxy, "https": proxy}

def search_url(keyword, page=1, per_page=60, category=0):
    params = {"_nkw": keyword, "_sacat": category,
              "_ipg": per_page, "_pgn": page}
    return "https://www.ebay.com/sch/i.html?" + urlencode(params)

r = requests.get(search_url("vintage seiko watch"),
                 proxies=proxies, timeout=20)
print(r.status_code)  # parse r.text with your HTML library of choice
eBayスクレイピングパイプラインの図: パラメータから検索URLを構築し、住宅プロキシを通じて取得し、リストを解析し、行を保存する
eBayの公開検索ページはAPIのように動作します — パラメータがクエリで、マークアップがレスポンスです。

売却済みおよび完了済みリスト: 実際の市場価格

これは価格に関して重要なエンドポイントです。アクティブなリストは売り手が望む価格を示すだけで、多くは売れません。eBayは、2つの追加パラメータを通じて同じ検索ページで実際の取引履歴を公開しています: LH_Complete=1はすべての完了済みリストを表示し、LH_Sold=1は実際に売れたアイテムに絞り込みます。売却済みリストでは、価格は最終販売価格であり、希望価格ではありません — これが物の本当の価値を示す最もクリーンな無料ソースです。

def sold_url(keyword, page=1):
    # append the completed + sold filters to any search
    return ("https://www.ebay.com/sch/i.html?"
            f"_nkw={keyword.replace(' ', '+')}"
            "&LH_Complete=1&LH_Sold=1"
            f"&_ipg=60&_pgn={page}")

# every sold row = a real transaction: use median, not mean,
# to shrug off outliers and shill bids
r = requests.get(sold_url("nike dunk low panda 10"),
                 proxies=proxies, timeout=20)

売却済みページは標準の検索と同じマークアップを使用しているため、リストパーサーは変更なしで処理できます — 2つのフィルターを追加するだけです。最後の30〜60の売却価格の中央値を取ることで、平均ではなく、再販や競合価格監視ワークフローが信頼できる堅牢な市場価値を得ることができます。

リストの解析: 価格、詳細、バリアント

単一バリアントのリストは簡単です: 価格は主要な価格要素にあり、アイテムの詳細テーブル(状態、ブランド、モデル、サイズ)はラベル/値のペアのセットであり、説明は別途取得できるiframeにあります。eBayの地域別価格変換に注意してください — 一部の地域では、元の価格と並んで変換された価格が表示されるため、両方をキャプチャします。

マルチバリアント製品(モデル、ストレージ、カラーオプションを持つ電話など)は、JavaScriptによってオプションごとの価格が更新されるため、より複雑です。そのデータは可視HTMLにはなく、<script>タグ内のMSKUというJavaScript変数に格納された隠れたウェブデータです。そのJSONを抽出すれば、ページをレンダリングせずにすべてのバリアントの価格と在庫を一度に取得できます。

import re, json

def extract_msku(html):
    # the variant matrix lives in a JS object keyed 'MSKU'
    m = re.search(r'"MSKU"\s*:\s*(\{.*?\})\s*[,}]', html, re.S)
    if not m:
        return {}          # single-variant listing, no matrix
    data = json.loads(m.group(1))
    # data now holds per-variant price, currency and stock flags
    return data

variants = extract_msku(r.text)
アクティブなeBayリストを希望価格として、売却済みリストを実際の最終取引価格として比較する
評価のためには、常に売却済みフィルターをスクレイピングしてください: アクティブな価格は希望であり、売却済みの価格が市場です。

大規模にブロックされないようにする

1つのリストは簡単です。規模が問題になると、eBayはレート制限、CAPTCHAチャレンジ、および自動化パターンをフラグする動的コンテンツで反撃します。データセンターIPはマーケットプレイスで迅速に制限されます。信頼できる解決策は、通常のショッパーとして振る舞う住宅プロキシで、単一のIPが明らかなバーストを蓄積しないように回転させることです。リクエストをペース配分し、429を受けたらバックオフし、地域固有の価格が必要な場合は出口をローカライズしてください。eBayは地域ごとに結果と通貨を調整します。

ターゲットがより厳しいボット管理を追加した場合や、解析と回転スタックを自分で維持したくない場合は、Scraper APIがIP回転、JSレンダリング、リトライを1つのエンドポイントの背後で処理し、クリーンなHTML、JSON、またはmarkdownを返します。より広範なマーケットプレイスのプレイブックについては、Amazon、eBay、Etsyを横断するマーケットプレイス自動化に関するガイドでアカウントの安全性と地域ターゲティングをカバーしています。

クリーンな住宅プロキシでeBayをスクレイピングする

スクレイピングからデータセットへ

行が流れ始めたら、重複排除と履歴が重要です。eBayのアイテムIDで各レコードをキーにして、再スクレイピングが既存の行を更新し、重複を避けるようにし、価格をタイムスタンプとアイテムの状態と共に保存します — 売却価格はその日付とアイテムが新品か中古かと一緒でなければ意味がありません。各製品ごとに最近の売却データのローリングウィンドウを保持すれば、自己更新するライブ評価が得られ、これが再販、再価格設定、またはアービトラージツールの基盤となります。突然の価格変動にアラートを組み合わせると、データセットが自動で監視を始めます。

eBayのスクレイピングは合法ですか?

これは一般的な情報であり、法的アドバイスではありません。公開されているリストデータ — 価格、状態、売却履歴 — を敬意を持って収集することは、広く合法と見なされています。注意すべきラインは個人データです: 売り手の名前、所在地、連絡先はEUのGDPRや他の地域の類似法の下で保護されているため、合法的な根拠なしに保存しないようにしてください。市場のシグナルをスクレイピングし、人々をスクレイピングしないでください。

よくある質問

eBayの売却済みリストをどのようにスクレイピングしますか?

任意のeBay検索URLにLH_Complete=1&LH_Sold=1を追加します。それにより、実際に売れた完了済みリストに結果が切り替わり、表示された価格が最終取引価格になります。ページは通常の検索と同じマークアップを使用しているため、同じパーサーがタイトル、価格、販売日を抽出して価格調査に利用できます。

公式APIなしでeBayの価格をスクレイピングできますか?

はい。公開された検索およびリストページは、購入者が見るすべてを返し、クォータやOAuthはありません。検索パラメータ(_nkw_sacat_pgn_ipg)がクエリとページネーションを駆動し、製品ページには価格、アイテムの詳細、バリアントデータが含まれています。レート制限を受けずにボリュームを維持するには、回転する住宅プロキシが必要です。

eBayのバリアント価格をどのように取得しますか?

マルチオプションリストは、MSKUという名前のJavaScriptオブジェクトにオプションごとの価格と在庫を格納し、スクリプトタグに埋め込まれています。可視HTMLにはありません。そのJSONブロックを抽出すれば、ページをレンダリングしたり各オプションをクリックしたりせずに、すべての組み合わせの価格を取得できます — ブラウザを操作するよりもはるかに速く信頼性があります。

なぜ私のeBayスクレイパーはブロックされるのですか?

eBayは自動化されたように見えるトラフィックに対してレート制限とCAPTCHAチャレンジを適用し、データセンターIP範囲は迅速に制限されます。回転する住宅IPにリクエストを分散し、遅延を持たせてペースを調整し、429を受けたらバックオフし、ヘッダーを一貫させてください。チャレンジが続く場合は、IPを回転させ、JavaScriptをレンダリングするScraper APIがメンテナンスの負担を軽減します。

検索ページをAPIのようにスクレイピングし、2つのパラメータで売却履歴を解放し、埋め込まれたJSONからバリアントマトリックスを抽出し、すべてをクリーンな住宅IPを通してルーティングします。これを行えば、eBayはあなたが制御するライブ価格データセットになります。

スタックを管理せずにeBayデータを抽出する