Shopifyで販売しているなら、競合の多くもおそらくShopifyを使っており、その価格、割引、在庫状況はストアを開けば誰でも見られます。監視アプリはそれをダッシュボードにまとめてくれますが、同じデータを自分で、関心のあるストアと商品に絞って収集し、履歴を手元に残すこともできます。これは1つのストアの運営者の規模で行うプライスインテリジェンスであり、Shopifyは多くのプラットフォームよりも最初の一歩が簡単です。
このガイドでは、データの所在、商品ごとに記録すべき項目、国ごとのマーケットの比較方法、そして安定して運用する方法を説明します。
自分で構築する理由
アプリはすぐに使い始められますが、制約もあります。多くの場合、競合や商品の数に上限があり、更新のタイミングはアプリ側が決め、生の履歴データはアプリの中に残ります。自前の小さなコレクターなら、次のものが手に入ります。
- 自分で決めた競合リスト。 どのアプリも追跡していない小さなストアも含められます。
- 自分で決めたスケジュール。 たとえばセール中は数時間ごと、それ以外は1日1回です。
- 自分のデータ。 自社の売上や利益率と突き合わせられるスプレッドシートやデータベースに保存できます。
その代わり、多少の設定と、リクエストを丁寧かつ一定に保つ工夫が必要で、そこでプロキシが役立ちます。
データの所在:公開されている商品JSON
多くのShopifyストアは、公開カタログを機械で読める形式で公開しています。
/products.jsonは、商品とそのバリエーションをページ単位で一覧にします。大きなカタログは?limit=250&page=2のように付けて順にたどります。/products/<handle>.jsonは1つの商品を返します。handleは商品URLの末尾の部分です。/collections/<handle>/products.jsonはコレクション内の商品を一覧にします。特定のカテゴリだけを追う場合に便利です。
各バリエーションには必要な項目がそろっています。price、compare_at_price(取り消し線の付いた「通常価格」)、available、sku、そしてタイムスタンプです。画像やスクリプトを含むレンダリング済みの商品ページを読み込むよりはるかに軽く、ストアがテーマを変えても変わりません。
すべてのストアが公開しているわけではありません。エラーやパスワードページを返すストアもあり、ヘッドレス構成のストアではそもそも提供されていないこともあります。その場合は、商品ページに埋め込まれた構造化データを読みます。この方法はHTMLを解析する代わりにJSON-LDを抽出するで解説しています。
商品ごとに記録する項目
商品ではなくバリエーションを追跡します。5サイズあるTシャツは5つのバリエーションであり、競合は売れ残っているサイズだけを値下げすることがよくあります。
バリエーションごと、チェックごとに記録する項目:
- ストア、商品のhandle、バリエーションID、SKU、バリエーション名(サイズ、色)。
priceとcompare_at_price。available(在庫の有無)。- チェックした時刻、チェック元の国、表示された通貨。
算出するシグナル:
- 割引の深さ:
compare_at_priceとpriceの差、そして割引の開始と終了のタイミング。 - 価格変更: バリエーションの価格が動くたびに、変更前と変更後の値を記録します。
- 在庫切れ: 在庫なしに切り替わったバリエーション。需要の強さや供給の問題を示すことが多いシグナルです。
- 新商品と削除された商品: 競合が投入した商品と、ひっそり取り下げた商品。
変更点と1日1回のスナップショットだけを保存すれば、数十のストアを追っても履歴は小さく保てます。
マーケット:同じストアでも国によって価格が違う
Shopify Marketsを使うと、1つのストアが多くの国で現地通貨を使い、しばしば異なる価格で販売できます。訪問者に表示されるマーケットは、通常その所在地で決まり、/en-ca/ のような国別サブフォルダや通貨セレクターが使われることもあります。
これは監視にとって重要です。1つの国にある1台のサーバーからすべてを収集すると、そのマーケットしか見えません。米国、英国、ドイツの購入者が支払う価格を比較するには、次のようにします。
- 販売している各国のIPからストアにアクセスします。 そうすることで、ストアは現地の購入者向けのマーケットを選びます。
- 受け取った通貨と価格をそのまま記録します。 換算した値は記録しません。
- 最初はマーケットごとに1商品を手作業で確認します。 レンダリングされたページと比べ、収集したJSONがそのストアの現地価格を示していることを確かめます。
ほとんどのShopifyの比較には国単位のターゲティングで十分です。都市単位のターゲティングが意味を持つのは、ストアが地域ごとに配送オプションや在庫を変える場合だけです。
最小限のコレクター
以下のスクリプトは、プロキシ経由で1つのストアのカタログを読み込み、各バリエーションの価格と在庫を出力します。ストアと国ごとにスケジュール実行し、行をデータベースに書き込んでください。
import time
import requests
PROXY = "http://customer-USERNAME-country-us:PASSWORD@p.shifter.io:443"
STORE = "https://competitor-store.example"
def fetch_catalogue(store):
page = 1
while True:
r = requests.get(
f"{store}/products.json",
params={"limit": 250, "page": page},
proxies={"http": PROXY, "https": PROXY},
timeout=30,
)
r.raise_for_status()
products = r.json().get("products", [])
if not products:
break
yield from products
page += 1
time.sleep(2) # stay polite between pages
for product in fetch_catalogue(STORE):
for v in product["variants"]:
print(product["handle"], v["id"], v["title"],
v["price"], v["compare_at_price"], v["available"])
ユーザー名の country-us を変更すると、別のマーケットの購入者が見るのと同じ状態でストアを収集できます。
プロキシの設定
| 作業 | ローテーション | ターゲティング |
|---|---|---|
| カタログの日次スナップショット | リクエストごと | マーケットの国 |
| セール中の主要商品の頻繁なチェック | リクエストごと | マーケットの国 |
| カートやチェックアウト合計の確認 | スティッキーセッション | マーケットの国 |
Shopifyのストアは1つのアドレスがページを要求できる速度を制限しており、毎日同じストアにアクセスする監視サーバーはすぐに目立ちます。リクエストごとに新しいIPを使うレジデンシャルプロキシなら、チェックを対象国の実際の家庭回線に分散できるため、ストアは現地の購入者に対するのと同じように応答します。
収集を安定させるための習慣をいくつか紹介します。
- 同じストアのページ間では1〜2秒の間隔を空け、ストアを1日の中で分散させます。
- 主要商品は頻繁に、カタログ全体は1日1回チェックします。ほとんどの価格は1時間単位では動きません。適切な頻度を決めるには、オンライン価格の変動の速さに関する調査が参考になります。
- HTMLのレスポンスやチャレンジページはデータではなく失敗として扱い、時間を置いて再試行します。
より大きな仕組みへの組み込み方
Shopifyストアは全体像の一部にすぎないことがほとんどです。サプライヤーやマーケットプレイスも追跡しているなら、ドロップシッピング向けプロキシのガイドで、競合ストアと並んで商品リサーチやサプライヤー監視を扱っています。
まとめ
競合のShopifyストアを監視するのにアプリは必要ありません。公開されている商品JSONを読み、各バリエーションの価格、「通常価格」、在庫をチェックの時刻と国とともに記録し、変更点だけを保存します。各マーケットはその国のIPから収集し、ローテーションするレジデンシャルプロキシを使えば、毎日のスケジュールをブロックなしで回せます。