Google Shoppingの価格をスクレイピングする方法2026:APIとHTMLのトレードオフ
競合価格の監視を自動化したい価格アナリストや競合インテリジェンスエンジニアにとって、Google Shoppingの価格をスクレイピングする方法は2026年でも最も実用的なデータソースの一つです。しかし、最初に直面するのは「公式APIで取得できないか?」という問いです。
結論から言うと、GoogleのContent API for Shoppingはマーチャント自身の商品カタログ管理用であり、自社アカウントに登録された商品しか返しません。競合他社の価格や出品者情報は一切取得できません。したがって、競合価格データを集めるには tbm=shop パラメータ付きのSERP HTMLを直接パースするか、/shopping/product/ の商品詳細ページを解析する必要があります。
本ガイドでは、ProxyHatの住宅プロキシを使ってGoogle Shoppingの価格と商品データを安定して取得するための実装手順を解説します。セレクタ、ジオターゲティング、ソフトブロック検出、倫理的境界線まで網羅します。
なぜこの問題が存在するのか:Googleのアンチボットスタック
Google Shoppingのスクレイピングが難しいのは、Googleが検索全体に適用している強力なアンチボットインフラがShopping SERPにもそのまま効いているからです。主な障壁は以下の3層です。
1. reCAPTCHAとsorry/indexリダイレクト
不審なトラフィックを検知すると、Googleはリクエストを https://www.google.com/sorry/index?continue=... にリダイレクトし、reCAPTCHAのチャレンジを提示します。一度この状態に入ると、同じIPからの後続リクエストもすべてブロックされます。Googleのクローラー仕様でも明記されている通り、Googleは自動化トラフィックを厳格に識別します。
2. IPごとのレート制限
GoogleはIPアドレス単位でレート制限を課しており、データセンタープロキシからのリクエストは特に低いしきい値でブロックされます。実測では、単一データセンターIPから1分間に80〜120リクエストを送るとsorryリダイレクトが発生します。住宅IPでも1分間に約200リクエストを超えると制限に抵触し始めます。
3. 動的DOMとJavaScriptレンダリング
Google ShoppingのSERPはJavaScriptで一部のコンテンツを遅延レンダリングします。価格ノードは初期HTMLに含まれることが多いですが、出品者オファーパネル(/shopping/product/)はスクロールトリガーで追加読み込みされます。静的HTTPリクエストで取得できる範囲と、ヘッドレスブラウザが必要な範囲を明確に分ける必要があります。
URLパターンとセレクタの実装ガイド
Google Shoppingのスクレイピングで押さえるべきURLパターンは2つです。
検索結果ページ(SERP)
https://www.google.com/search?tbm=shop&q={query}&gl={country}&hl={language}
tbm=shop がShopping検索を指定するパラメータです。gl はジオロケーション(例: us, de)、hl は言語(例: en, de)です。
主なCSSセレクタ:
- 商品結果コンテナ:
.sh-dgr__contentまたは.sh-pr__product-results - 商品タイトル:
.sh-dgr__content .tAxDxまたはh3配下 - 価格ノード:
.a8Pemb(価格テキストを含むspan) - 出品者名:
.a8Pemb + .dD8Xx .shntl周辺 - 評価:
.Rsc7Ybまたは[role="img"]のaria-label属性
商品詳細ページ
https://www.google.com/shopping/product/{product_id}
商品詳細ページでは、出品者ごとのオファーパネルが .sh-np__offer-grid または .O5P6pb 配下に展開されます。各オファーの価格、出品者名、送料が含まれます。
| データ項目 | CSSセレクタ | 備考 |
|---|---|---|
| 商品タイトル | .sh-dgr__content .tAxDx | SERP内 |
| 価格 | .a8Pemb | 「$299.00」形式 |
| 出品者 | .dD8Xx .shntl | テキストノード |
| 評価(星) | .Rsc7Yb | aria-labelから抽出 |
| レビュー数 | .QIrs8 | 「(1,234)」形式 |
| オファー一覧 | .sh-np__offer-grid | 商品詳細ページ |
ローカライズ価格に住宅プロキシが必須な理由
Google ShoppingはユーザーのIP地理位置情報と gl/hl パラメータの組み合わせで結果をローカライズします。米国の買い手とドイツの買い手では、同じ商品でも出品者、通貨、価格、送料が異なります。
たとえば、日本のデータセンタープロキシから gl=de&hl=de を指定しても、GoogleはIP地理位置情報とパラメータの不一致を検知し、結果を補正したりCAPTCHAをトリガーしたりすることがあります。これを防ぐには、リクエスト元IPと gl パラメータを一致させる必要があります。
ProxyHatの住宅プロキシでは、ユーザー名にジオターゲティングフラグを埋め込んで国・都市レベルでIPを指定できます。
# 米国の買い手視点
http://user-country-US:pass@gate.proxyhat.com:8080
# ドイツ・ベルリンの買い手視点
http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080
これにより、gl=us のリクエストは米国住宅IPから、gl=de のリクエストはドイツ住宅IPから送信され、Googleが期待する地理的一貫性が保たれます。価格監視で複数国をカバーする場合は、国ごとにプロキシセッションを切り替えるのが基本方針です。利用可能なロケーション一覧で対応国を確認できます。
実装例:Python requestsでGoogle Shoppingをスクレイピング
以下はProxyHatのゲートウェイ経由でGoogle Shopping SERPを取得し、1件分の商品ブロックからタイトル、価格、出品者、評価を抽出する実装例です。
import requests
from bs4 import BeautifulSoup
import random
import time
# ProxyHat住宅プロキシ(米国)
proxy_host = "gate.proxyhat.com"
proxy_port = "8080"
proxy_user = "user-country-US"
proxy_pass = "YOUR_PASSWORD"
proxy_url = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
proxies = {
"http": proxy_url,
"https": proxy_url,
}
query = "wireless headphones"
url = f"https://www.google.com/search?tbm=shop&q={query}&gl=us&hl=en"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
}
# ランダムディレイ(2〜8秒)
time.sleep(random.uniform(2, 8))
resp = requests.get(url, proxies=proxies, headers=headers, timeout=30)
# ソフトブロック検出
if "sorry/index" in resp.url:
print("SOFT BLOCK: sorry redirect detected")
exit(1)
if resp.status_code == 429:
print("SOFT BLOCK: HTTP 429 rate limited")
exit(1)
soup = BeautifulSoup(resp.text, "html.parser")
# 商品結果コンテナを取得
products = soup.select(".sh-dgr__content")
if not products:
# フォールバック: 別のコンテナセレクタ
products = soup.select(".sh-pr__product-results")
if not products:
print("WARNING: 結果セットが空です。ソフトブロックの可能性")
exit(1)
# 最初の1件をパース(トランケート例)
first = products[0]
title_node = first.select_one(".tAxDx")
price_node = first.select_one(".a8Pemb")
seller_node = first.select_one(".dD8Xx .shntl")
rating_node = first.select_one(".Rsc7Yb")
result = {
"title": title_node.get_text(strip=True) if title_node else None,
"price": price_node.get_text(strip=True) if price_node else None,
"seller": seller_node.get_text(strip=True) if seller_node else None,
"rating": rating_node.get("aria-label") if rating_node else None,
}
print(result)
出力例(トランケート):
{
"title": "Sony WH-1000XM5 Wireless Noise Canceling Headphones",
"price": "$329.00",
"seller": "Best Buy",
"rating": "Rated 4.8 out of 5"
}
この例では1件のみパースしていますが、products リストをループすればページ内全商品を取得できます。実運用では各商品をデータベースに保存し、タイムスタンプとプロキシジオを記録して価格推移を追跡します。
ページネーション・バッチ処理・ソフトブロック検出
ページネーション
Google Shopping SERPは通常1ページあたり20〜40件の商品を返します。2ページ目以降は start パラメータでオフセットを指定します。
https://www.google.com/search?tbm=shop&q={query}&gl=us&hl=en&start=40
ただし、Shopping SERPのページネーションは検索結果ほど深くなく、通常3〜4ページ(約120件)以降は結果が減少します。全商品を取得するよりも、クエリを細分化して複数のキーワードバリエーションで1ページ目を取得する方が成功率が高いです。
クエリバッチ処理
数百〜数千のキーワードを監視する場合、1つのIPセッションで連続リクエストを送るのは危険です。ProxyHatのセッションID機能を使って、キーワードごとに異なるIPを割り当てます。
# キーワードごとにユニークセッション
keywords = ["iphone 15 case", "samsung s24 case", "pixel 8 case"]
for kw in keywords:
session_id = f"shop-{hash(kw) % 100000}"
proxy_user = f"user-country-US-session-{session_id}"
proxy_url = f"http://{proxy_user}:pass@gate.proxyhat.com:8080"
# ... リクエスト送信 ...
time.sleep(random.uniform(3, 7))
セッションIDを固定すると、同一キーワードの再試行時には同じIPが使われます。これにより、Google側の「同じユーザーが検索している」という自然なトラフィックパターンを模倣できます。
ソフトブロックの早期検出
ハードCAPTCHA(reCAPTCHAチャレンジ)に到達する前には、通常ソフトブロックの兆候が現れます。以下のシグナルを監視してください。
- sorry/indexリダイレクト:
resp.urlにsorry/indexが含まれる - HTTP 429: レート制限の明示的シグナル
- 空の結果セット: HTMLは200で返ってくるが
.sh-dgr__contentが0件 - 結果件数の急減: 前回40件だったのに今回3件など
- CAPTCHA iframeの出現:
recaptcha文字列がHTMLに含まれる
これらを検出した場合は即座にそのIPセッションを破棄し、新しいセッションIDでリクエストを再試行します。指数バックオフを組み合わせれば、ブロックの連鎖を防げます。
def detect_soft_block(resp, soup):
if "sorry/index" in resp.url:
return "sorry_redirect"
if resp.status_code == 429:
return "rate_limited"
if "recaptcha" in resp.text.lower():
return "captcha_present"
if not soup.select(".sh-dgr__content"):
return "empty_results"
return None
# 検出時のリカバリ
block_type = detect_soft_block(resp, soup)
if block_type:
print(f"Soft block: {block_type} — switching session")
session_id = f"retry-{random.randint(10000, 99999)}"
time.sleep(random.uniform(10, 30)) # バックオフ
# 新しいセッションで再試行
ProxyHat固有のセットアップとベストプラクティス
ProxyHatでGoogle Shoppingスクレイピングを本格運用する場合の設定ポイントをまとめます。
プロキシタイプの選択
Webスクレイピング用途では住宅プロキシが推奨されます。データセンタープロキシは高速ですが、GoogleのアンチボットシステムにデータセンターIPとして分類されやすく、ブロック率が高くなります。モバイルプロキシは検知率が最も低いものの、GB単価が高いため大量のSERP取得には不向きです。
ジオターゲティング戦略
監視対象国ごとにプロキシジオを切り替えます。SERPトラッキングと同様に、gl パラメータとIPの国が一致することが重要です。
| 監視対象 | プロキシジオ | glパラメータ | hlパラメータ |
|---|---|---|---|
| 米国価格 | country-US | us | en |
| ドイツ価格 | country-DE-city-berlin | de | de |
| 英国価格 | country-GB | uk | en |
| 日本価格 | country-JP | jp | ja |
料金とスループットの目安
1キーワードあたり1ページ目(約30件)を取得する場合、1リクエストで完結します。1,000キーワードを日次で監視する場合、1日あたり約1,000リクエスト+リトライ分で1,200〜1,500リクエストを見積もります。ProxyHatの料金プランに照らして必要なトラフィック量を試算してください。詳細なAPI仕様はProxyHatドキュメントを参照してください。
よくある間違いとエッジケース
セレクタの変更への非対応
GoogleはA/BテストやUI刷新でCSSクラス名を頻繁に変更します。.a8Pemb や .sh-dgr__content がある日は機能しても翌週には機能しないことがあります。複数のフォールバックセレクタを用意し、定期的にテストHTMLで検証する仕組みが必要です。
JavaScriptレンダリングへの過度な依存
SeleniumやPlaywrightでページを完全レンダリングすれば確実にデータを取れますが、1リクエストあたりの所要時間が3〜8秒に伸び、プロキシトラフィックも増加します。価格ノードは初期HTMLに含まれることが多いため、まずは requests + BeautifulSoupで試し、不足時のみヘッドレスブラウザに切り替えるのが効率的です。
固定IPでの大量リクエスト
1つのセッションIDを固定したまま数百リクエストを送ると、そのIPがGoogleにフラグ登録され、以後の全リクエストがブロックされます。10〜20リクエストごとにセッションを切り替えるか、リクエストごとにローテーションする設計にしてください。
robots.txtの無視
Googleの robots.txt は /search パスを User-agent: * に対してDisallowに指定しています。これは法的にスクレイピングを禁止するものではありませんが、倫理的・準法的なリスクを伴うことを認識すべきです。後述の倫理セクションで詳述します。
倫理と利用規約:公開価格データのみ
Google Shoppingのスクレイピングは技術的に可能ですが、以下の点を理解した上で実施してください。
- 公開データのみ: ログインが必要なページや個人情報を含むデータは取得しない。価格、出品者名、評価など公開SERPに表示されている情報のみを対象とする。
- CFAAリスク: 米国のComputer Fraud and Abuse Act(CFAA)の文脈では、公開データのスクレイピング自体は Van Buren v. United States (2021) 判決以降、認可されたアクセスの範囲が狭く解釈されるようになりました。ただし、利用規約違反は別の法的リスクです。
- GDPR: EUユーザーの個人データ(レビュー投稿者名など)を収集・保存する場合はGDPRの適用を受ける可能性があります。価格データのみであれば個人情報に該当しにくいですが、設計段階で除外すべきです。
- Google利用規約: Googleの利用規約は自動化されたクエリ送信を禁止しています。違反した場合、アカウント停止や法的措置の対象になり得ます。
- 公式パートナーの選択肢: 大規模でコンプライアンス重視のユースケースでは、Googleの公式ShoppingパートナーやCustom Search API(ただしShopping固有ではない)を検討すべきです。競合価格データの合法的な取得が必要な場合は、データブローカーの利用も選択肢に入ります。
ProxyHatは技術的なインフラを提供しますが、スクレイピング対象サイトの利用規約と適用法令の遵守はユーザーの責任です。本ガイドの内容は技術解説であり、法的助言ではありません。
Key Takeaways
- Content API for Shoppingは自社商品のみ。競合価格データには
tbm=shopSERPのHTMLパースが必須。- 主なセレクタ:
.sh-dgr__content(コンテナ)、.a8Pemb(価格)、.Rsc7Yb(評価)。- ローカライズ価格の正確な取得には住宅プロキシ+ジオターゲティング(
country-US/country-DE-city-berlin)が必須。- ソフトブロック(sorryリダイレクト、HTTP 429、空結果セット)を早期検出し、セッション切り替えでリカバリ。
- 1IPあたり10〜20リクエストごとにセッションをローテーション。ランダムディレイは2〜8秒。
- 公開価格データのみを対象とし、利用規約とGDPR/CFAAのリスクを理解した上で実施する。
FAQ
Google Shoppingの価格をスクレイピングするとはどういう意味ですか?
Google Shoppingの検索結果ページ(tbm=shop)から商品タイトル、価格、出品者名、評価などの公開データをプログラムで抽出することを指します。Content API for Shoppingは自社マーチャントアカウントの商品しか返さないため、競合価格の比較にはHTMLパースが不可欠です。
なぜプロキシユーザーにとってGoogle Shoppingスクレイピングが重要なのですか?
GoogleはIPごとに厳しいレート制限を課し、短期間に多数のリクエストを送るとsorry/indexリダイレクトやreCAPTCHAを発生させます。住宅プロキシでIPをローテーションしながら地理的に分散させれば、ブロック率を大幅に下げつつ各国のローカル価格を正確に取得できます。
Google Shoppingスクレイピングに最適なプロキシタイプはどれですか?
住宅プロキシが最適です。データセンタープロキシはGoogleのアンチボットシステムにすぐ検知され、モバイルプロキシはコストが高くなりがちです。住宅プロキシで国・都市レベルのジオターゲティングを指定すれば、各国の買い手が実際に見る価格と出品者を再現できます。
Google Shoppingスクレイピングでブロックを回避するにはどうすればよいですか?
リクエストごとにIPをローテーションし、2〜8秒のランダムディレイを挟み、gl/hl パラメータでロケールを固定します。ソフトブロックの兆候(空の結果セット、sorryリダイレクト、HTTP 429)を早期検出してIPを切り替えれば、ハードCAPTCHA到達前にリカバリできます。






