How to Scrape Temu Product and Price Data in 2026: Proxies, Anti-Bot, and the Hidden JSON

A practical guide to scraping Temu product and price data at scale—covering the internal JSON endpoints, anti-bot bypass with curl_cffi, residential proxy geo-targeting, and a worked Python example.

How to Scrape Temu Product and Price Data in 2026: Proxies, Anti-Bot, and the Hidden JSON
In this article

How to Scrape Temu Product and Price Data in 2026: The API-vs-HTML Trade-Off

If you're building a price-intelligence pipeline, you've likely asked how to scrape Temu product and price data in 2026. The platform offers no public API for catalog access, so you're left choosing between two approaches: parsing volatile HTML product cards, or reverse-engineering the internal JSON endpoints that power Temu's listing grids and product detail pages. Each path has distinct trade-offs in reliability, maintenance cost, and anti-bot exposure.

The HTML route means you depend on hashed CSS class names that change with every frontend deploy. A selector like ._2rss6Z7 for the price element might work today and break tomorrow. The JSON route—hitting endpoints like /api/poppy/v1/search or the goods-detail API—returns structured data that's far more stable, but these endpoints require signed headers and tokens that Temu's frontend generates dynamically through obfuscated JavaScript.

There's also a third hybrid approach: extracting the embedded __NEXT_DATA__ state blob from the HTML response. This gives you structured JSON without needing to replicate the anti_content token, making it the most practical entry point for most scraping projects. We'll cover all three approaches below.

Temu's Anti-Bot Stack: What You're Up Against

Temu runs a multi-layered anti-bot defense that goes well beyond simple IP rate limiting. Understanding each layer is critical before you write a single line of scraping code. Let's break down the three primary defenses.

Cloudflare Turnstile and JS Challenges

Temu uses Cloudflare Turnstile alongside traditional JavaScript challenges to filter automated traffic. Turnstile evaluates browser fingerprints, TLS characteristics, and behavioral signals before issuing a clearance token. If your HTTP client doesn't execute JavaScript or presents a mismatched fingerprint, you'll receive a challenge page instead of product data. Unlike legacy CAPTCHAs, Turnstile operates invisibly—there's no puzzle to solve, which means you won't even know you've been blocked until you inspect the response HTML.

The Signed anti_content Token

Beyond Cloudflare, Temu's own API layer requires an anti_content header—a signed token generated client-side through heavily obfuscated JavaScript. This token encodes browser environment data, timestamps, mouse movement patterns, and request parameters. Without it, the JSON endpoints return empty results or HTTP 403 error codes. Replicating this token requires either executing the JS in a headless browser (like Playwright or Puppeteer) or reverse-engineering the signing algorithm, which Temu updates frequently—sometimes weekly.

This is why the embedded __NEXT_DATA__ approach is often more practical: you get structured JSON from a standard HTML page without needing to generate the anti_content token yourself. The trade-off is that you're limited to whatever data the server-side render includes.

TLS and HTTP/2 Fingerprinting

Even if you pass the JS challenge, Temu inspects the TLS handshake and HTTP/2 frame ordering to identify non-browser clients. Standard Python libraries like requests or httpx produce JA3/JA4 fingerprints that don't match real browsers, flagging your requests instantly. Datacenter IPs compound this problem—Temu's edge can distinguish ASN ranges associated with cloud providers (AWS, GCP, Azure, DigitalOcean) and applies stricter thresholds to them. A request from a datacenter IP with a non-browser TLS fingerprint is effectively a double flag.

This is where curl_cffi becomes essential. It wraps libcurl-impersonate, which reproduces the exact TLS handshake and HTTP/2 settings of specific Chrome, Firefox, or Safari versions. Combined with residential proxies, this combination addresses both the fingerprint and IP reputation layers simultaneously.

Locating the Data: HTML State Blobs and JSON Endpoints

Once you're past the anti-bot layer, you need to know where the product data actually lives. Temu's frontend is built on Next.js, which means the server renders an initial HTML payload with embedded state.

The Embedded __NEXT_DATA__ Blob

The most reliable data source in the HTML response is the __NEXT_DATA__ script tag. Temu's Next.js frontend hydrates from a serialized JSON blob embedded in a <script id="__NEXT_DATA__" type="application/json"> tag. This blob contains the full product, pricing, SKU, and shipping data before any client-side rendering. Because it's server-rendered, it's more stable than CSS selectors and doesn't require the anti_content token.

The structure typically nests as: props.pageProps.store or props.pageProps.initialState, depending on the page type. For product detail pages, you'll find goods_id, goods_name, min_normal_price, sku_list, and shipping metadata at this level.

Key JSON Endpoints

If you need search results rather than individual product pages, the listing grid is powered by internal API calls. The two most useful endpoints are:

  • /api/poppy/v1/search — returns search results with product IDs, titles, prices, ratings, and sales counts. Requires anti_content header, search_key, and pagination parameters.
  • Goods detail API — returns full SKU lists, variant pricing, shipping costs, and stock status for a single product. Accessed via goods_id parameter.

Both endpoints return JSON, but both require the anti_content token. If you can't generate it, stick to the __NEXT_DATA__ extraction approach.

Hashed CSS Classes and data-uniqid Attributes

If you must parse the rendered DOM, look for data-uniqid attributes on product cards—these are more stable than class names and often contain the goods_id directly. Price elements frequently use hashed classes like ._2rss6Z7 or attributes like [data-testid*="price"], but these change with each frontend deploy. Always prefer the embedded JSON blob over DOM parsing when possible.

Rate Limits and Why Residential Proxies with Geo-Targeting Are Mandatory

Temu applies aggressive rate limiting that varies by endpoint, IP reputation, and geographic region. Based on empirical testing, unauthenticated requests from a single residential IP are typically throttled at approximately 60–80 requests per minute before receiving HTTP 429 responses. Datacenter IPs hit this ceiling much faster—often after only 15–20 requests—because Temu's WAF assigns lower trust scores to cloud-provider ASN ranges.

More importantly, prices and shipping costs on Temu vary by region. A product listed at $4.98 in one US state may show different shipping fees, delivery estimates, or even availability in another. If your price-intelligence pipeline needs region-accurate data, you must route requests through proxies geo-located to the target market. A datacenter proxy in Virginia will return different pricing than a residential IP in California.

Residential vs Datacenter vs Mobile Proxies for Temu

Proxy TypeAnti-Bot EvasionGeo AccuracyRelative CostBest For
ResidentialHigh — real ISP IPsCountry + CityMediumPrice monitoring, SERP scraping, catalog crawling
DatacenterLow — flagged quicklyCountry onlyLowTesting, non-blocked endpoints, low-stakes tasks
MobileHighest — carrier-grade IPsCountry + CityHighHigh-value targets, strictest anti-bot scenarios

For Temu specifically, residential proxies with city-level targeting (e.g., -country-US) are the practical sweet spot. They use real ISP IP ranges that pass Temu's ASN checks, and you can pin requests to specific cities to capture regional pricing differences. Check our proxy locations page for available geo-targeting options.

Worked Example: Fetching Temu Product Data with Python and ProxyHat

Here's a practical implementation using curl_cffi for TLS-fingerprint spoofing combined with ProxyHat residential proxies. curl_cffi impersonates real browser TLS handshakes, which is essential for bypassing Temu's JA3/JA4 fingerprint checks.

Step 1: Install Dependencies

pip install curl_cffi

Step 2: Fetch a Product Page Through ProxyHat

from curl_cffi import requests
import json
import re

# ProxyHat residential proxy with US geo-targeting
proxy_url = "http://user-country-US:YOUR_PASSWORD@gate.proxyhat.com:8080"

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",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Referer": "https://www.temu.com/",
}

# curl_cffi impersonates Chrome's TLS + HTTP/2 fingerprint
response = requests.get(
    "https://www.temu.com/goods.html?goods_id=123456789",
    headers=headers,
    proxies={"http": proxy_url, "https": proxy_url},
    impersonate="chrome120",
    timeout=30,
)

print(f"Status: {response.status_code}, Size: {len(response.text)} bytes")

Step 3: Parse the Embedded JSON Blob

def extract_next_data(html: str) -> dict:
    """Extract the __NEXT_DATA__ JSON blob from Temu HTML."""
    pattern = r'<script id="__NEXT_DATA__"[^>]*>(.*?)</script>'
    match = re.search(pattern, html, re.DOTALL)
    if not match:
        raise ValueError("No __NEXT_DATA__ blob found — possible block page")
    return json.loads(match.group(1))

data = extract_next_data(response.text)
store = data.get("props", {}).get("pageProps", {}).get("store", {})

# Truncated sample of the parsed structure:
# {
#   "goods_id": "123456789",
#   "goods_name": "Wireless Earbuds Bluetooth 5.3",
#   "min_normal_price": {"amount": 4.98, "currency": "USD"},
#   "sku_list": [
#     {"sku_id": "sku_001", "spec": "Black", "price": 4.98},
#     {"sku_id": "sku_002", "spec": "White", "price": 5.49}
#   ],
#   "shipping_info": {"free_threshold": 0, "estimated_days": "5-7"}
# }

goods_id = store.get("goods_id")
goods_name = store.get("goods_name")
price = store.get("min_normal_price", {}).get("amount")
sku_list = store.get("sku_list", [])

print(f"Product: {goods_name} (ID: {goods_id})")
print(f"Price: ${price} | SKUs: {len(sku_list)}")

Step 4: Hitting the JSON Search Endpoint Directly

# Direct API call — requires valid anti_content token
# Use this only if you can generate the token via headless browser
api_url = "https://www.temu.com/api/poppy/v1/search"

params = {
    "search_key": "wireless earbuds",
    "page": 1,
    "page_size": 50,
    "sort": "default",
}

api_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",
    "Anti-Content": "YOUR_GENERATED_TOKEN",
    "Referer": "https://www.temu.com/search_result.html?search_key=wireless+earbuds",
    "Accept": "application/json, text/plain, */*",
}

response = requests.get(
    api_url,
    params=params,
    headers=api_headers,
    proxies={"http": proxy_url, "https": proxy_url},
    impersonate="chrome120",
    timeout=30,
)

# Truncated sample response:
# {
#   "data": {
#     "items": [
#       {"goods_id": "123456789", "title": "Wireless Earbuds...",
#        "price": {"amount": 4.98, "currency": "USD"},
#        "sales": 12500, "rating": 4.6}
#     ],
#     "total": 3500,
#     "has_more": true
#   },
#   "success": true
# }

result = response.json()
items = result.get("data", {}).get("items", [])
print(f"Found {len(items)} products on page {params['page']}")

Sticky Sessions, Retries, and Pagination

For multi-step workflows—like fetching a product page, then checking cart shipping costs—IP consistency matters. If your IP rotates between requests, Temu may flag the session as suspicious or return inconsistent regional pricing. Use ProxyHat's sticky sessions to pin a series of requests to the same exit IP.

Sticky Session Configuration

import time
import random

session_id = "temu_batch_01"
session_proxy = f"http://user-session-{session_id}-country-US:YOUR_PASSWORD@gate.proxyhat.com:8080"

product_ids = ["123456789", "987654321", "456789123"]
request_count = 0

for goods_id in product_ids:
    response = requests.get(
        f"https://www.temu.com/goods.html?goods_id={goods_id}",
        headers=headers,
        proxies={"http": session_proxy, "https": session_proxy},
        impersonate="chrome120",
        timeout=30,
    )
    request_count += 1

    if response.status_code == 200:
        data = extract_next_data(response.text)
        process_product(data)
    elif response.status_code == 429:
        # Rotate to a new sticky session on rate limit
        session_id = f"temu_batch_{request_count:04d}"
        session_proxy = f"http://user-session-{session_id}-country-US:YOUR_PASSWORD@gate.proxyhat.com:8080"
        time.sleep(random.uniform(5, 10))  # Back off
    else:
        time.sleep(random.uniform(2, 5))

    # Randomized delay between requests
    time.sleep(random.uniform(2, 5))

Pagination Strategy

Temu paginates search results with a page parameter. Keep pagination depth reasonable—going beyond page 20–30 often yields diminishing returns and increases block risk significantly. A practical approach for large-scale collection:

  • Limit to 10–15 pages per search query per sticky session
  • Rotate to a new sticky session every 50–80 requests
  • Add randomized delays of 2–5 seconds between requests to mimic human browsing patterns
  • Retry failed requests up to 3 times with exponential backoff (2s, 4s, 8s)
  • Distribute queries across multiple concurrent sessions to increase throughput

ProxyHat supports up to 100 concurrent sessions on standard plans—see our pricing page for details on session limits and bandwidth allowances.

Scraping e-commerce data exists in a legal gray area. Before you build a Temu price scraper, consider the following guidelines carefully.

Public Catalog Data Only

Stick to publicly accessible product listings, prices, and availability. Do not scrape user account data, personal reviews tied to identifiable users, or any content behind authentication. The Computer Fraud and Abuse Act (CFAA) in the US and the GDPR in the EU both create significant liability for accessing non-public data or scraping personal information. While public catalog data is generally less risky, you should consult legal counsel before deploying any scraping pipeline at scale.

Respect robots.txt and Rate Limits

Check Temu's robots.txt and respect its directives. Even if a path is technically disallowed, scraping it may violate Temu's Terms of Service. Keep your request rate reasonable—aggressive scraping that degrades service for other users is both unethical and more likely to trigger permanent IP bans. A good rule of thumb: if your scraping volume would be noticeable in Temu's traffic analytics, you're going too fast.

When to Use the Official Merchant Feed

If you're a Temu seller or authorized partner, the Temu merchant center provides product feed APIs that are the legitimate alternative to scraping. For price-intelligence use cases where you're monitoring competitors, scraping public catalog data may be the only option—but keep it scoped, respectful, and compliant with applicable laws.

For broader guidance on ethical scraping practices, see our web scraping use case guide and SERP tracking documentation. Full proxy configuration details are available in the ProxyHat documentation.

Key Takeaways

  • Prefer the embedded JSON blob over HTML parsing. The __NEXT_DATA__ state blob gives you structured product data without needing the anti_content token, and it's more stable than hashed CSS selectors.
  • Residential proxies with city-level geo are mandatory. Temu's anti-bot flags datacenter IPs within 15–20 requests, and regional pricing varies by location. Use -country-US or finer geo-targeting for accurate data.
  • Use curl_cffi for TLS fingerprint matching. Standard HTTP libraries produce non-browser JA3/JA4 fingerprints that get blocked instantly. curl_cffi with impersonate="chrome120" solves this.
  • Sticky sessions for multi-step workflows. Pin related requests to the same IP with -session- flags to maintain cart and shipping consistency.
  • Stay ethical and legal. Scrape only public catalog data, respect rate limits, and use the official merchant feed API if you're an authorized partner.

Frequently asked questions

What is the best method to scrape Temu product and price data?

The best method is to fetch product pages with curl_cffi (for TLS fingerprint matching) through residential proxies, then extract the embedded __NEXT_DATA__ JSON blob from the HTML. This approach gives you structured product data—including goods_id, price, SKU lists, and shipping info—without needing to reverse-engineer Temu's signed anti_content token. For search results, the internal /api/poppy/v1/search endpoint returns JSON but requires the anti_content header, making it harder to use without a headless browser.

Why do residential proxies matter when scraping Temu?

Temu's anti-bot system flags datacenter IP ranges from cloud providers (AWS, GCP, Azure) within 15–20 requests, while residential IPs can sustain 60–80 requests per minute. Additionally, Temu's prices and shipping costs vary by geographic region, so you need proxies geo-located to your target market. Residential proxies with country or city-level targeting (e.g., -country-US) provide both the IP reputation and geographic accuracy needed for reliable price-intelligence data.

Which proxy type works best for Temu price scraping?

Residential proxies are the best choice for Temu scraping. They use real ISP IP ranges that pass Temu's ASN reputation checks, support country and city-level geo-targeting for region-accurate pricing, and cost less than mobile proxies. Datacenter proxies are flagged too quickly to be useful for production scraping. Mobile proxies offer the highest evasion but at a premium cost—reserve them for the strictest anti-bot scenarios where residential IPs fail.

How do you avoid anti-bot blocks when scraping Temu?

Use four strategies together: (1) curl_cffi with impersonate='chrome120' to match real browser TLS/HTTP2 fingerprints, (2) residential proxies with geo-targeting to avoid datacenter ASN flags, (3) sticky sessions to maintain IP consistency across multi-step workflows, and (4) randomized delays of 2–5 seconds between requests with exponential backoff on HTTP 429 responses. Rotate to a new sticky session every 50–80 requests and limit pagination depth to 10–15 pages per query.

Is it legal to scrape Temu product data?

Scraping publicly accessible catalog data (product names, prices, availability) is generally lower risk than scraping authenticated or personal data. However, the CFAA in the US and GDPR in the EU create liability for accessing non-public data or scraping personal information. Always check Temu's robots.txt and Terms of Service, respect rate limits, and avoid scraping user accounts or personal reviews. If you're an authorized Temu seller, use the official merchant feed API instead. Consult legal counsel before deploying any scraping pipeline at scale.

Ready to get started?

Access 50M+ residential IPs across 148+ countries with AI-powered filtering.

View PricingResidential Proxies
← Back to Blog