In this Article

scrape google shopping

In this Article

Googleショッピングのスクレイピングとは、Googleのショッピング結果からタイトル、価格、販売者、評価、配送情報といった構造化された商品データを大規模に収集することを指す。これらの結果は厳重に保護され地域ごとに異なるため、単一の接続で単一のスクレイパーを使うのではなく、IPをローテーションし正確な地域指定を行うことが安定した収集には不可欠となる。

本ガイドはコード中心である。地域指定リクエスト、国別プロキシによるルーティング、Googleが意図的に難読化する商品カードの解析、ページネーション、レート制限時のリトライとバックオフ、同意ダイアログに対応するヘッドレスブラウザのフォールバック、CSVエクスポート付きのクリーンなデータモデル、価格履歴トラッカー、監視スケジュールまでを扱う。また、アンチボットの現実、自作スクレイパーと有料SERP APIとのトレードオフ、法的な境界線についても正直に述べる。

DataImpulseは、195か国に及ぶ9000万を超えるレジデンシャル・モバイル・データセンターIPアドレスを提供する倫理的なプロキシプロバイダーである。1GBあたり1ドルからの従量課金モデルを採用し、トラフィックの有効期限はない。Webスクレイピング、広告検証、価格監視、市場調査、マルチアカウント管理などに利用されている。

重要事実

  • ローカライズされた価格設定: Googleショッピングを正確にスクレイピングするには、glとhlパラメータを設定し、対象国のIPを経由してリクエストをルーティングする必要がある。価格、販売者、在庫状況は地域によって異なるためである。
  • 最適なプロキシの種類: 実際の消費者IPを使用し、検出を回避できるローテーション型レジデンシャルプロキシ。
  • 価格: 1GBあたり1ドルから、従量課金制で、トラフィックの有効期限なし、サブスクリプション不要。
  • カバレッジ: 195か国にわたる9000万件以上の倫理的に調達されたIP。
  • 信頼性: 成功率99.51%、G2で5段階中4.8の評価。
  • プロトコルとターゲティング: HTTP、HTTPS、SOCKS5に対応し、国別ターゲティングが標準で含まれる。
Googleショッピングの商品データを収集する

Googleショッピングからどのようなデータを取得できるか?

Googleショッピングは、価格設定や市場調査に役立つ複数の構造化フィールドを持つ商品リストを公開している。各結果は通常、抽出して行として正規化できる一貫した属性セットを持つ。

  • 商品の詳細: タイトル、説明の抜粋、ブランド、モデル、商品画像URL。
  • 価格: 表示価格、通貨、および場合によっては販売者間の価格帯。
  • 販売者: 販売者名と、商品詳細ページに表示される同一商品を扱う他の販売者の一覧。
  • 評価とレビュー: 表示される場合の総合評価とレビュー件数。
  • 在庫状況と配送: 在庫状況と、地域によって異なる配送に関する注記。

正確なフィールド構成はGoogleがレイアウトを更新するたびに変わるため、パーサーは欠損値や変化するマークアップに耐えられる必要がある。評価や販売者が常に存在すると仮定せず、すべてのフィールドを任意項目として扱い、抽出後に型を検証すること。同じ商品が国によって異なる価格で表示され得るため、後から地域情報を追加するのではなく、最初から(商品、国、タイムスタンプ)をキーとするスキーマを設計しておくとよい。

Googleショッピングに地域指定リクエストを送信するには?

地域指定リクエストを送信するには、ショッピングタブのフラグとロケールパラメータを付けてGoogleの検索エンドポイントにアクセスし、実際の買い物客が送信するのと同じIPおよびパラメータの信号を読み取らせる。最も重要な2つのパラメータは gl (国を指定するもので、例えば gl=de はドイツを指す)、そして hl (インターフェース言語を指定するもので、例えば hl=de)。3つ目に役立つのは、 locationのような、クエリのコンテキストに組み込む項目だが、 gl と一致する出口IPを組み合わせることでほとんどの作業が完了する。

パラメータを設定するだけでは不十分である。GoogleはリクエストのIPも読み取り、どの価格や販売者を表示するかを決定するためである。以下の最小構成のリクエストは、現実的なヘッダーとロケールのペアを送信する。IP層を追加する前の基本的な呼び出しを確認できるよう、意図的にプロキシを介していない。

import requests

def build_params(query, country="us", lang="en", start=0):
    return {
        "q": query,
        "tbm": "shop",   # shopping vertical
        "gl": country,    # country bias, e.g. de, gb, fr
        "hl": lang,       # interface language
        "num": 40,        # results per page (soft cap)
        "start": start,   # pagination offset
    }

HEADERS = {
    "User-Agent": (
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/124.0 Safari/537.36"
    ),
    "Accept-Language": "en-US,en;q=0.9",
}

resp = requests.get(
    "https://www.google.com/search",
    params=build_params("wireless headphones", country="us", lang="en"),
    headers=HEADERS,
    timeout=30,
)
print(resp.status_code, len(resp.text))

Accept-Language ヘッダーを hlに合わせておくこと。ドイツの価格ページに対して英語の言語ヘッダーでリクエストするのは不自然に見えるだけでなく、誤った通貨が返される原因にもなる不整合である。規模を拡大する際には、この基本関数がロケールを決定する唯一の場所となり、以降のすべての呼び出しの一貫性を保つことができる。

国別ターゲティングされたプロキシ経由でリクエストをルーティングするには?

国別ターゲティングに対応したプロキシ経由でリクエストを送るには、 requests を単一のゲートウェイに向け、対象国をプロキシのユーザー名にエンコードする。DataImpulseの場合、ゲートウェイは gw.dataimpulse.com:823であり、ユーザー名の末尾に __cr.usまたは__cr.de を追加すると出口国を選択できる。国別ターゲティングは基本料金に含まれるが、州、市区町村、郵便番号、ASNによるターゲティングは有料オプションとなる。プロキシ認証に不慣れな場合は、 プロキシ認証に関するガイドで、ユーザー名とパスワードの仕組みを詳しく解説している。

import requests

USER = "your_login"
PASS = "your_password"
GATEWAY = "gw.dataimpulse.com:823"

def proxy_for(country):
    # __cr. pins the exit IP to that country
    cred = f"{USER}__cr.{country}:{PASS}"
    url = f"http://{cred}@{GATEWAY}"
    return {"http": url, "https": url}

resp = requests.get(
    "https://www.google.com/search",
    params=build_params("wireless headphones", country="de", lang="de"),
    headers=HEADERS,
    proxies=proxy_for("de"),
    timeout=30,
)
print(resp.status_code, len(resp.text))

重要なのは、プロキシの国と gl/hl の組み合わせを常に一緒に切り替えることである。複数市場の価格比較を構築するには、国のリストをループし、出口IPとロケールを常に連動させることで、各レスポンスが一貫した購入者の所在地を反映するようにする。

MARKETS = [
    {"country": "us", "lang": "en"},
    {"country": "de", "lang": "de"},
    {"country": "gb", "lang": "en"},
    {"country": "fr", "lang": "fr"},
]

def fetch_market(query, market):
    c, lang = market["country"], market["lang"]
    return requests.get(
        "https://www.google.com/search",
        params=build_params(query, country=c, lang=lang),
        headers={**HEADERS, "Accept-Language": f"{lang};q=0.9"},
        proxies=proxy_for(c),
        timeout=30,
    )

for m in MARKETS:
    r = fetch_market("wireless headphones", m)
    print(m["country"], r.status_code, len(r.text))

DataImpulseが提供するのはIP層であり、マネージド型のスクレイピングサービスではないため、スクレイパー自体は自分で運用することになる。ローテーション型の レジデンシャルプロキシ は実際の消費者端末由来のIPを利用できるため、この用途に適している。データセンタープロキシ は安価だが検出されやすく、モバイルプロキシ は特に難しい対象向けに通信事業者のIPを提供する。

Googleショッピングの商品カードを解析するには?

商品カードは、壊れやすい深いセレクタではなく、安定したテキストパターンに基づいて寛容なHTMLライブラリで解析する。Googleのクラス名は難読化されており頻繁に変更されるためである。今日ブラウザの開発者ツールからコピーしたセレクタも数週間以内に壊れる可能性があるため、レイアウト変更でクラッシュするのではなく、優雅に劣化するようパーサーを構築すること。

堅牢なアプローチでは、各候補カードを読み取り、タグ構造からタイトルと画像を抽出し、通貨を考慮した正規表現で価格を抽出する。以下のセレクタは現実的な例であって保証ではない。更新が必要になることを見込み、正規表現を信頼できるフォールバックとして維持すること。

from bs4 import BeautifulSoup
import re

# Currency-aware price matcher: symbol optional, thousands and decimals tolerated.
PRICE_RE = re.compile(r"(?:[$€£]|USD|EUR|GBP)\s?\d[\d.,]*")

def parse_cards(html):
    soup = BeautifulSoup(html, "html.parser")
    rows = []
    # These class names ROTATE; treat them as hints, keep the fallbacks.
    candidates = soup.select("div.sh-dgr__content, div.sh-dlr__list-result, div[data-docid]")
    if not candidates:
        candidates = soup.find_all("div")  # last-resort sweep
    for card in candidates:
        text = card.get_text(" ", strip=True)
        price_match = PRICE_RE.search(text)
        if not price_match or len(text) > 400:
            continue
        img = card.find("img")
        link = card.find("a", href=True)
        rows.append({
            "title": _first_text(card, ["h3", "h4"]),
            "price_raw": price_match.group(0),
            "image": img.get("src") if img else None,
            "url": link["href"] if link else None,
        })
    return rows

def _first_text(card, tags):
    for t in tags:
        el = card.find(t)
        if el and el.get_text(strip=True):
            return el.get_text(strip=True)
    return None

CURRENCY = {"$": "USD", "€": "EUR", "£": "GBP"}

def normalize_price(raw):
    if not raw:
        return None, None
    symbol = next((s for s in CURRENCY if s in raw), None)
    code = CURRENCY.get(symbol, "USD")
    digits = re.sub(r"[^\d.,]", "", raw).replace(",", "")
    try:
        return float(digits), code
    except ValueError:
        return None, code

ここでは難読化されたマークアップが常態であるため、レンダリング済みDOMに頼るチームもある。静的HTMLの解析とレンダリング済みページの解析の幅広いトレードオフについては、 動的Webページのスクレイピングを参照してほしい。

Googleが429を返した場合、どのようにページネーションとバックオフを行うか?

ページネーションは、 start オフセットをページサイズに合わせた間隔で進めることで行う。レート制限に対処するには、HTTP 429、空のレスポンス、CAPTCHAを待機後に新しいIPで再試行すべき合図として扱う。Googleは繰り返される自動リクエストを積極的に制限するため、ページネーションとバックオフは同じループに組み込む必要がある。

リクエストがカードを返さなくなるか、ページ上限に達するまでページを進める。プロキシの辞書を読み直すことでページ間で出口IPをローテーションし、ステータスコードだけに頼るのではなく、本文中の同意またはCAPTCHAのマーカーを確認してソフトブロックを検出する。

BLOCK_MARKERS = ("unusual traffic", "/sorry/", "consent.google", "captcha")

def is_blocked(resp):
    if resp.status_code in (429, 503):
        return True
    body = resp.text.lower()
    return any(m in body for m in BLOCK_MARKERS)

def paginate(query, market, max_pages=5, page_size=40):
    all_rows = []
    for page in range(max_pages):
        params = build_params(query, market["country"], market["lang"],
                              start=page * page_size)
        resp = get_with_retry(
            "https://www.google.com/search",
            params=params, proxies=proxy_for(market["country"]),
        )
        if resp is None:
            break
        rows = parse_cards(resp.text)
        if not rows:
            break  # no more results
        all_rows.extend(rows)
    return all_rows

以下のリトライヘルパーはジッター付き指数バックオフを使用しており、これによりブロックされたワーカーの群れが同じ瞬間に一斉に再試行することを防ぐ。各試行でプロキシ辞書を再取得するため、ローテーションプールは次の試行で新しいIPを提供する。

import time, random

def get_with_retry(url, params, proxies, max_attempts=4):
    for attempt in range(max_attempts):
        try:
            resp = requests.get(url, params=params, headers=HEADERS,
                                proxies=proxies, timeout=30)
        except requests.RequestException:
            resp = None
        if resp is not None and not is_blocked(resp):
            return resp
        # exponential backoff: 2, 4, 8 seconds, plus jitter
        wait = (2 ** (attempt + 1)) + random.uniform(0, 1.5)
        time.sleep(wait)
    return None  # exhausted; caller decides what to do

リトライが成功する場合でも、リクエストレートは妥当な範囲に保つこと。ページ間の丁寧な基本遅延をローテーションと組み合わせる方が、連打してリトライに頼るよりも長期的な安定性に寄与する。ペーシングとヘッダーの取り扱いについては、 Webスクレイピングのベストプラクティス に関する解説を参照してほしい。

ヘッドレスブラウザでブロックされたページをレンダリングするには?

単純なHTTPリクエストが同意の壁やJavaScriptでレンダリングされるコンテンツに繰り返し阻まれる場合は、実際のクライアントのようにページを実行し、DOMを読み取る前に同意ダイアログを閉じるヘッドレスブラウザにフォールバックする。Playwrightはコンテキストごとのプロキシと信頼できる待機処理をサポートしているため適している。

以下のスクリプトは、国別ターゲティングしたDataImpulseプロキシ経由でChromiumを起動し、欧州のロケールで通常表示されるCookieまたは同意ダイアログを処理する。コンテンツを待ってからレンダリング済みHTMLを返すため、同じ parse_cards 関数に渡せる。

from playwright.sync_api import sync_playwright

def render_shopping(query, country="de", lang="de"):
    cred_user = f"{USER}__cr.{country}"
    params = f"?q={query.replace(' ', '+')}&tbm=shop&gl={country}&hl={lang}"
    url = "https://www.google.com/search" + params
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        context = browser.new_context(
            proxy={
                "server": "http://gw.dataimpulse.com:823",
                "username": cred_user,
                "password": PASS,
            },
            locale=f"{lang}-{country.upper()}",
            user_agent=HEADERS["User-Agent"],
        )
        page = context.new_page()
        page.goto(url, wait_until="domcontentloaded", timeout=45000)
        _dismiss_consent(page)
        page.wait_for_timeout(2000)
        html = page.content()
        browser.close()
        return html

def _dismiss_consent(page):
    # Consent dialogs vary by locale; try a few common accept buttons.
    for label in ("Accept all", "Alle akzeptieren", "Tout accepter",
                  "I agree", "Accept"):
        try:
            btn = page.get_by_role("button", name=label)
            if btn.count() > 0:
                btn.first.click(timeout=3000)
                page.wait_for_timeout(1000)
                return
        except Exception:
            continue

ヘッドレスブラウザは生のリクエストよりもCPUとメモリの負荷が大きいため、デフォルトの経路ではなく、本当にレンダリングが必要なページに対する的を絞ったフォールバックとして使用すること。多くのチームは速度のために直接HTTPを実行し、 is_blocked が繰り返し発火する場合にのみPlaywrightへ切り替える。スタックがPythonではなくJavaScriptの場合も、Puppeteerで同じパターンを適用できる。詳しくは JavaScriptによるWebスクレイピングを参照してほしい。

スクレイピングしたデータをどのように構造化しエクスポートするか?

データは、常に市場情報とキャプチャのタイムスタンプを含む安定したレコードを中心に構造化し、その後CSVにエクスポートすることで、差分比較、スプレッドシートへの読み込み、あるいはデータウェアハウスへの投入が容易になる。dataclassを使うことで型ヒントが得られ、1行の定義が明確になる。

from dataclasses import dataclass, asdict, field
from datetime import datetime, timezone
import csv

@dataclass
class Offer:
    query: str
    country: str
    title: str | None
    price: float | None
    currency: str | None
    seller: str | None = None
    url: str | None = None
    captured_at: str = field(
        default_factory=lambda: datetime.now(timezone.utc).isoformat()
    )

def to_offers(rows, query, country):
    offers = []
    for r in rows:
        price, currency = normalize_price(r.get("price_raw"))
        offers.append(Offer(
            query=query, country=country, title=r.get("title"),
            price=price, currency=currency, url=r.get("url"),
        ))
    return offers

CSVの書き込みは、dataclassのフィールドを書き出すだけの作業になる。追記モードとヘッダーガードを組み合わせることで、スケジュールされたジョブが1つのファイルを書き換えることなく時間をかけて成長させられる。

import os

def export_csv(offers, path="google_shopping.csv"):
    if not offers:
        return
    fieldnames = list(asdict(offers[0]).keys())
    write_header = not os.path.exists(path)
    with open(path, "a", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        if write_header:
            writer.writeheader()
        for o in offers:
            writer.writerow(asdict(o))

各行に国とタイムスタンプを保持しておくことで、後になって「今日どの市場でこのSKUが最も安いか」や「今週価格がどう動いたか」といった質問に答えられるようになる。この地理と時間のキーが、次のセクションで扱う価格履歴トラッカーの基盤となる。

Googleショッピングの価格履歴を時系列で追跡するには?

価格履歴の追跡は、商品・国・日付をキーとする小さなデータベースに各観測結果をアップサートすることで行う。これにより、スクレイパーを再実行しても過去の日のデータを保持したまま今日の行が更新されるだけで、重複することはない。SQLiteは数百万行でも十分対応でき、サーバーも不要なため、監視ジョブを自己完結型に保てる。

以下のスキーマは複合ユニークキーと ON CONFLICT によるアップサートを使用する。同じ日にスクレイパーを2回実行すると、その(商品、国、日)の最新価格が上書きされる。複数日にわたって実行することで、後でグラフ化できる時系列データが構築される。

import sqlite3

DDL = """
CREATE TABLE IF NOT EXISTS price_history (
    product   TEXT NOT NULL,
    country   TEXT NOT NULL,
    day       TEXT NOT NULL,
    price     REAL,
    currency  TEXT,
    seller    TEXT,
    captured_at TEXT,
    PRIMARY KEY (product, country, day)
);
"""

def init_db(path="prices.db"):
    conn = sqlite3.connect(path)
    conn.execute(DDL)
    conn.commit()
    return conn

def upsert_offers(conn, offers):
    sql = """
    INSERT INTO price_history
        (product, country, day, price, currency, seller, captured_at)
    VALUES (?, ?, ?, ?, ?, ?, ?)
    ON CONFLICT(product, country, day) DO UPDATE SET
        price=excluded.price,
        currency=excluded.currency,
        seller=excluded.seller,
        captured_at=excluded.captured_at;
    """
    for o in offers:
        day = o.captured_at[:10]  # YYYY-MM-DD
        conn.execute(sql, (o.title, o.country, day, o.price,
                           o.currency, o.seller, o.captured_at))
    conn.commit()

def price_trend(conn, product, country, days=14):
    cur = conn.execute(
        """SELECT day, price, currency FROM price_history
           WHERE product = ? AND country = ?
           ORDER BY day DESC LIMIT ?""",
        (product, country, days),
    )
    return cur.fetchall()

実際には、日をまたいでタイトルを一致させることが最も難しい部分である。Googleのタイトルは取得のたびにわずかに変化するためだ。小規模な監視リストであれば、抽出したタイトルを安定したキーとして使うのではなく、アップサート前に生のタイトルを自分で管理する正規の商品IDにマッピングするとよい。

継続的な価格モニタリングをどのようにスケジュールするか?

監視のスケジューリングは、取得・解析・保存の各ステップを1つのエントリーポイントにまとめ、cronで一定の間隔で実行することによって行う。これにより手動実行なしで価格が自動的に更新される。価格追跡の場合、1日1回の実行が妥当なデフォルトである。それより頻繁な実行は、ほとんどのカタログにおいて有効なシグナルをさほど増やさないまま、コストとブロックリスクの両方を高めてしまう。

# run_monitor.py
def run_once(queries):
    conn = init_db()
    for query in queries:
        for market in MARKETS:
            rows = paginate(query, market, max_pages=3)
            offers = to_offers(rows, query, market["country"])
            export_csv(offers)
            upsert_offers(conn, offers)
            print(f"{query} / {market['country']}: {len(offers)} offers")
    conn.close()

if __name__ == "__main__":
    WATCHLIST = ["wireless headphones", "mechanical keyboard"]
    run_once(WATCHLIST)

次に、それをcronに登録する。以下のエントリは毎日06:15に監視処理を実行し、デバッグ用に出力をログに記録する。これは重要である。というのも、スケジュールされたスクレイパーはそうしなければ静かに失敗するからだ。

# crontab -e
# minute hour day month weekday  command
15 6 * * * cd /opt/shopping && /usr/bin/python3 run_monitor.py >> monitor.log 2>&1

ジョブ内に軽いジッターを追加し(開始時に数分間のランダムな待機を入れる)、リクエストが毎日まったく同じ秒にGoogleへ届かないようにする。前述の通り出口国をローテーションさせリクエストの間隔を調整し、ブロック率の上昇がないかログを注視すること。これはGoogleが防御策を変更したか、あなたのパターンが規則的になりすぎたことを示す最も早い兆候である。

DIY、隠しエンドポイント、SERP API、ヘッドレスのどの収集方式を選ぶべきか?

どれだけの脆弱性とエンジニアリング負担を引き受ける意志があるかと、リクエストごとにどれだけ支払う意志があるかを基準に選ぶこと。唯一の正解はない。正直なところ、トレードオフは制御とコストか、それとも保守負担とアンチボットへの露出かという選択である。

アンチボットの現実: Googleはレート制限、CAPTCHA、同意の壁、ローテーションする難読化マークアップ、行動シグナルを用いてこれらの結果を積極的に防御している。自作のスクレイパーは定期的に壊れ、継続的なメンテナンスが必要になる。プロキシとバックオフはブロックを減らすが、なくすわけではない。永久にブロックされないGoogleスクレイパーを約束する者は誇大宣伝している。

方式 コスト 脆弱性 制御性
DIYによるHTML解析 低(プロキシのみ) 高い 完全
隠しJSONエンドポイント 低(プロキシのみ) 非常に高い 完全
SERP API 高(リクエスト単位) 低い 限定的
ヘッドレスブラウザ 中(計算資源+プロキシ) 中程度 完全

SERP APIとDIYの比較: サードパーティのSERP APIは、解析済みのショッピング結果をJSONで返し、リクエストごとの料金とベンダーロックインを伴う代わりに、解析とブロック回避を代行する。プロキシを使う自作スクレイパーはリクエストあたりのコストが大幅に低く、完全に制御できる一方で、Googleの変更時にはパーサー、リトライ、保守を自分で担う必要がある。DataImpulseの位置付けを明確にすると、これはDIY方式の下で使うプロキシ層であり、SERP APIでもマネージド型スクレイピングサービスでもない。解析作業を一切行いたくないならSERP APIが適しており、低コストと制御性を重視しスクレイパーを保守できるなら、ローテーションプロキシを使うDIYの方が経済的である。隠しJSONエンドポイントはさらに安価になり得るが、Googleが予告なく変更または削除できるため、最も脆弱な方法でもある。

Googleショッピングをスクレイピングすることは合法かつ倫理的か?

公開されている商品データのスクレイピングは、一般的に非公開または制限されたコンテンツへのアクセスよりもリスクが低いとみなされるが、ルールが全くないわけではなく、これは法的助言ではない。Googleショッピングの価格や掲載情報は公開されているが、それをどのように収集し利用するかは依然として重要であり、具体的なケースについては資格のある弁護士に確認するべきである。

  • 利用規約: 自動化されたアクセスはGoogleの規約と衝突する可能性があり、これは著作権法やコンピュータアクセス法とは別の契約上の問題である。
  • 個人データ: 商品の掲載情報は通常個人データではないが、レビュアー名やその他の識別子の収集は避け、適用される場合はGDPRに従うこと。
  • レートと負荷: 問い合わせている対象のサービスを劣化させないよう、リクエスト量を妥当な範囲に保つこと。
  • データ利用: 著作権で保護された画像や説明文をそのまま再利用することは、価格を事実として分析するよりも大きなリスクを伴う。

収集の側面において、倫理は使用するIPから始まる。DataImpulseは、同意しかつ報酬を受け取っているユーザーからIPを調達し、GDPRに準拠し、データ処理契約を提供しており、これが正当性のあるパイプラインを支えている。同意、調達、責任ある実践についてより詳しく知りたい場合は、 倫理的なWebスクレイピング倫理的なIPソースと、丁寧なペーシング、そしてデータの限定的かつ事実に基づく利用を組み合わせることで、法的リスクと評判リスクの両方を低く抑えられる。

Googleショッピングのデータを取得する方法

よくある質問

Googleショッピングのスクレイピングにレジデンシャルプロキシは必要か?

レジデンシャルプロキシは、通常のトラフィックに溶け込みやすい実際の消費者IPを使用するため、最も信頼性の高い選択肢である。データセンタープロキシは少量の利用では機能する場合もあるが、より検出されやすくブロックされやすい。

Googleショッピングからローカライズされた価格を取得するには?

glとhlパラメータを対象の国と言語に設定し、国別構文を使ってその同じ国のプロキシIPを経由してリクエストをルーティングする。例えばドイツの場合は__cr.deで終わるユーザー名を使う。GoogleはパラメータとリクエストのIPの両方を読み取り、どの価格を表示するか決定する。

DataImpulseはGoogleショッピングのスクレイピングAPIか?

いいえ。DataImpulseが提供するのはプロキシ層(レジデンシャル、モバイル、データセンターIP)であり、マネージド型のスクレイピングAPIやSERP APIではない。そのIPの上で自分自身のスクレイパーやサードパーティ製ツールを実行することになる。

なぜGoogleショッピングのスクレイパーがブロックされ続けるのか?

Googleは単一のIPから繰り返される自動リクエストを制限し、CAPTCHAや同意画面を表示する。ローテーション型レジデンシャルプロキシ、実際のブラウザに近いヘッダー、HTTP 429に対する指数バックオフ、適切なリクエスト頻度によってブロックは大幅に減らせるが、完全に防ぐ方法はない。

SERP APIを使うべきか、自分でスクレイパーを構築すべきか?

SERP APIは解析とブロック回避の作業を代行してくれるが、リクエストあたりのコストは高く、制御性も低い。これはメンテナンスをゼロにしたいチームに向いている。ローテーションプロキシを使った自作スクレイパーはコストがはるかに低く完全な制御が得られるが、Googleの変更に合わせてパーサーとリトライを自分で維持する必要がある。

DataImpulseが適さないのはどのような場合か?

固定ISPプロキシ、完全マネージド型のスクレイピングAPI、または銀行・政府サイトへのアクセスが必要な場合、DataImpulseは適切な選択肢ではない。DataImpulseは、公開データの収集やコンテンツへのアクセス向けに、ローテーション型のレジデンシャル、モバイル、データセンタープロキシを提供している。

信頼できるプロキシでGoogleショッピングのスクレイピングを始めよう

複数の市場にわたってGoogleショッピングのデータを収集する準備ができたなら、DataImpulseはローテーション型および固定型のレジデンシャル・モバイル・データセンターIPを、国別ターゲティング込みで1GBあたり1ドルから提供する。 アカウントを作成 して、最初のスクレイパーをクリーンなIPプール経由でルーティングしよう。


Share article: