AliExpressの製品データをドロップシッピング調査のためにスクレイピングする方法

AliExpressは製品データをHTMLではなくJavaScript変数に隠しています。そのJSONを取得すれば、価格、割引、発送元、販売数を1回のリクエストで得ることができます。ここでは、ブロックを回避するための手法を紹介します。

AliExpressは最大のグローバルマーケットプレイスであり、ドロップシッピング調査の主要な情報源です。価格と割引の履歴、実際に売れているもの、発送元、国ごとに変わるオファーを調査できます。2026年にはJavaScriptレンダリングとランダム化されたクラス名に依存しており、多くの人がフルブラウザを立ち上げることを恐れますが、通常は必要ありません。製品データはすでにページソース内のJavaScript変数にあります。それを抽出すれば、1回のリクエストでクリーンな構造化データを得ることができます。このガイドでは、隠されたJSONメソッド、AliExpressデータを価値あるものにする地理的次元、スクレイパーを維持するためのプロキシの手法を紹介します。

データはwindow.runParamsにあり、DOMにはありません

カテゴリまたは検索結果ページを開いてソースを表示します。すべての製品プレビューはwindow.runParamsというJavaScript変数に保存されており、<script>タグの中に隠されています。これは現代の一般的なパターンで、サーバーはデータをJSONとして送り、フロントエンドがクライアント側でレンダリングします。スクレイパーにとっては贈り物です。壊れやすいCSSセレクタを完全にスキップし、正規表現でスクリプトタグを引き出し、辞書のように解析します。この技術は隠れたウェブデータスクレイピングと呼ばれ、毎回のデプロイで変わるクラス名を追いかけるよりもはるかに耐久性があります。

import re, json, httpx

HEADERS = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                  "(KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
    "accept-language": "en-US,en;q=0.9",
}

PROXY = "http://USER:PASS@gate.quantumproxies.io:8000"

def get_run_params(html: str) -> dict:
    # The product data lives in window.runParams = {...};
    m = re.search(r"window\.runParams\s*=\s*(\{.+?\});", html, re.DOTALL)
    if not m:
        raise ValueError("runParams not found - page may be blocked or changed")
    return json.loads(m.group(1))

url = "https://www.aliexpress.com/category/.../catName.html"
r = httpx.get(url, headers=HEADERS, proxy=PROXY, timeout=30)
data = get_run_params(r.text)

調査に重要なフィールドを解析する

runParamsのデータは巨大なので、ドロップシッピングと価格調査に実際に使用されるフィールドだけを引き出します。リスティングタイトル、元の価格とセール価格、割引率、販売数、そして重要な発送元の国です。これは配送時間と購入者の信頼に影響を与えます。ネストは複雑に見えますが、安定しています。

def parse_items(data: dict) -> list[dict]:
    items = data.get("mods", {}).get("itemList", {}).get("content", [])
    out = []
    for it in items:
        prices = it.get("prices", {})
        sale = prices.get("salePrice", {})
        orig = prices.get("originalPrice", {})
        out.append({
            "id": it.get("productId"),
            "title": it.get("title", {}).get("displayTitle"),
            "sale_price": sale.get("minPrice"),
            "orig_price": orig.get("minPrice"),
            "discount_pct": sale.get("discount"),
            "currency": sale.get("currencyCode"),
            "sold": it.get("trade", {}).get("tradeDesc"),   # e.g. "1,000+ sold"
            "store_id": it.get("store", {}).get("storeId"),
        })
    return out

for row in parse_items(data)[:5]:
    print(row["title"][:40], row["sale_price"], f"-{row['discount_pct']}%", row["sold"])

その1回の呼び出しで製品の経済性を得ることができます。元の価格が$65.85でセール価格が$23.29に下がるリスティングは64%の割引であり、アイテムを仕入れる価値があるかどうかを示すマージンシグナルです。「販売数」は需要の指標であり、カテゴリ全体で組み合わせると、レビューページに触れることなく勝者をランク付けできます。

AliExpressページリクエスト、window.runParamsの正規表現抽出、解析された製品フィールドをJSONとして示すパイプライン図
リスティングデータはJavaScript変数にサーバーレンダリングされています。読み取るためにヘッドレスブラウザは必要ありません。

サイトを叩かずに検索ページネーションを行う

検索ページは既知の長さのページネーションを使用しているため、効率的な方法は次のとおりです。ページ1をスクレイピングし、レスポンスから総ページ数を読み取り、その後、制限内で残りを同時に取得します。すべてのページを一度に発射しないでください。AliExpressは積極的にレート制限を行い、403を返し始めます。並行性を控えめに保ち、各リクエストで出口IPを回転させます。

import asyncio, httpx

ROTATING = "http://USER:PASS@rotating.quantumproxies.io:8000"

async def fetch_page(client, query, page):
    url = f"https://www.aliexpress.com/w/wholesale-{query}.html?page={page}"
    for attempt in range(3):
        r = await client.get(url, headers=HEADERS, timeout=30)
        if r.status_code == 200:
            return parse_items(get_run_params(r.text))
        if r.status_code == 403:                 # blocked: back off, rotate exit
            await asyncio.sleep(2 ** attempt)
    return []

async def scrape_search(query, max_pages=5):
    async with httpx.AsyncClient(proxy=ROTATING) as client:
        sem = asyncio.Semaphore(3)               # gentle concurrency
        async def guarded(p):
            async with sem:
                return await fetch_page(client, query, p)
        pages = await asyncio.gather(*[guarded(p) for p in range(1, max_pages + 1)])
        return [row for page in pages for row in page]

results = asyncio.run(scrape_search("wireless earbuds"))
print(len(results), "products")

ここで重要なのは回転ゲートウェイです。1つのIPがページを次々と取得するのはブロックを受ける最速の方法であり、residential poolを介してリクエストごとに回転させることで負荷を分散し、どの出口も異常に見えないようにします。403に対する指数バックオフは、焼かれたIPが循環から外れる時間を与えます。

90M以上の住宅IPでAliExpressをスクレイピングする

地理がすべてのポイント

AliExpressは訪問者の場所によって価格、通貨、プロモーション、発送元倉庫をパーソナライズします。同じ製品が米国IPにはより速い配送を伴う米国ローカルカードを表示し、ヨーロッパのIPには異なる価格と起源を表示することがあります。ドロップシッピング調査において、その地理的次元がデータです。ターゲット市場の顧客が実際に何を見ているかを知りたいのです。販売する各市場で出口国を意図的に設定し、差異を記録します。ある地域で安くて現地発送される製品が、別の地域では遅くて高価である場合、非常に異なる賭けになります。ドロップシッピング調査のためのプロキシに関するガイドでは、これらのマトリックスを調達決定に変える方法をさらに詳しく説明しています。

# One product, three markets - compare price and ship-from per geo
MARKETS = {
    "us": "http://USER:PASS-country-us@gate.quantumproxies.io:8000",
    "de": "http://USER:PASS-country-de@gate.quantumproxies.io:8000",
    "br": "http://USER:PASS-country-br@gate.quantumproxies.io:8000",
}
for market, proxy in MARKETS.items():
    r = httpx.get(product_url, headers=HEADERS, proxy=proxy, timeout=30)
    d = get_run_params(r.text)
    # read price + shipFrom from the product detail runParams for this geo
    print(market, "->", extract_price_and_origin(d))

レビューと在庫は別の呼び出しにあります

リスティングは価格と需要を提供しますが、2つの高価値フィールドはそれぞれ独自のリクエストの背後にあります。顧客レビューは製品ページのrunParamsにはなく、専用のフィードバックエンドポイントから読み込まれ、ページネーションされています。そのため、評価とレビューのテキストを収集するには、メインページを解析するのではなく、製品ごとにその呼び出しを追う必要があります。在庫シグナルも同様です。リスティングの「販売数」は累積的な需要の指標であり、特定のバリアント(色、サイズ、発送元倉庫)の正確な在庫は、製品詳細ペイロードのSKUデータから得られます。ドロップシッピング調査において、これは重要です。なぜなら、価格と販売数で勝者のように見える製品が、あなたが販売したい特定のバリアントが市場に供給する倉庫で在庫切れである可能性があるからです。

2つを第2のパスとして扱います。まずリスティングをスクレイピングして、割引と販売数で候補をランク付けし、その後、レビューのページとバリアントごとの在庫でショートリストを強化します。それにより、リクエストボリュームとブロックリスクが各製品に対する真剣度に比例し、使用しないデータのためにすべてのリスティングを叩くことを避けられます。

DIYスクレイパーをスキップするタイミング

隠れたJSONメソッドは耐久性がありますが、AliExpressはペイロードの形状を変更し、レビューを別のエンドポイントの背後にゲートし、ボリュームに応じてブロックをエスカレートさせます。正規表現とリトライロジックを維持したくない場合、Scraper APIはURLを受け取り、解析されたJSONを返します。それはレンダリング、回転、ブロック防止層を処理し、1つのパラメータで地理ターゲットを設定できます。市場全体で数千の製品をスケジュールに従って収集する場合、これは実用的な選択です。クライアント側のペイロードから直接データを読み取る一般的なパターンについては、スクレイパーが空のページを返す理由に関するノートを参照してください。

403や地理的価格設定などのAliExpressスクレイピング障害を、住宅回転や地理ターゲティングなどの修正にマッピングするチェックリスト
3つの障害、3つの修正 — ほとんどのAliExpressスクレイパーの失敗はIP品質または地理的な問題です。

よくある質問

AliExpressの製品データをスクレイピングできますか?

はい。公開されているリスティングデータ(タイトル、価格、割引、販売数、画像、発送元)は、カテゴリ、検索、製品ページのwindow.runParams JavaScript変数に提供されています。正規表現で抽出し、JSONとして解析します。リスティングにはヘッドレスブラウザは必要ありません。AliExpressの利用規約とレート制限を尊重してください。

AliExpressには公開APIがありますか?

AliExpressはアフィリエイトとオープンプラットフォームAPIを提供していますが、承認が必要で、カバレッジが限定されており、プログラムに結び付けられています。カテゴリや市場を超えた広範な調査には、公開ページをスクレイピングすることで、より多くのフィールドと完全な地理制御を得ることができます。そのため、ほとんどのドロップシッピング研究者はページ上のJSONを抽出します。

AliExpressをスクレイピングする際に403エラーが発生するのはなぜですか?

403はAliExpressがリクエストをフラグしたことを意味します。通常、1つのIPからのヒットが多すぎる、データセンターの範囲、または薄いヘッダーセットが原因です。リクエストごとに住宅IPを回転させ、403に指数バックオフを追加し、現実的なUser-Agentとaccept-languageを送信し、並行性を低く保ちます。HTMLからrunParamsが欠落している場合、それはブロックであり、レイアウトの変更ではありません。

国別のAliExpress価格を取得するにはどうすればよいですか?

ターゲット国の出口IPを通じてリクエストをルートします。AliExpressは場所を読み取って通貨、価格、プロモーション、発送元倉庫を設定するため、米国IPとドイツIPでは同じ製品に対して異なるデータが表示されます。市場ごとにプロキシを地理ターゲットし、各バージョンを記録して価格の地理マトリックスを構築します。

勝利のアプローチは退屈で耐久性があります。ページがすでに送信しているJSONを読み取り、丁寧にページを移動し、クリーンな住宅IPを回転させ、関心のあるすべての市場を地理ターゲットします。それを行えば、AliExpressは403の壁ではなく、価格、需要シグナル、配送経済の信頼できる供給源になります。

Scraper APIから解析されたAliExpressデータを取得する