Your cart is currently empty!
Category: Uncategorized
-
How to Scrape Etsy Best Sellers and Trending Tags (2026)
Etsy surfaces its best-seller badges and trending tag labels on public product pages, and scraping them at scale is genuinely useful for competitive research, niche validation, and dropshipping product discovery. The catch is that Etsy runs aggressive bot detection, rate-limits unauthenticated crawlers hard, and returns different HTML depending on whether your request looks like a browser or a script. Here is a practical 2026 guide to getting the data reliably.
What Data You Can Actually Pull
Etsy does not expose a public API for best-seller or trending data. Everything you care about lives in rendered HTML or embedded JSON-LD on product and search pages.
Useful fields per listing:
- Listing title, price, sale price
- “Bestseller” badge (a
with classwt-badge--small) - Star rating and review count
- Shop name and sales count
- Tags (visible on listing pages, not search results)
- Estimated monthly sales (inferred from review velocity, not served directly)
Trending tags appear in Etsy’s search autocomplete (
/api/v3/ajax/typeahead/etsy/term) and in the “Shop by popular tags” carousels on category pages. Both endpoints are accessible without login but require consistent headers.How Etsy Detects Bots
Before writing a single line of code, understand the detection stack you are up against:
Layer Method Notes TLS fingerprinting JA3/JA4 hash check Requests/httpx fail without spoofing Header validation User-Agent, Accept, Sec-Fetch-* Missing Sec-Fetch headers = instant block IP reputation DataDome (embedded on most pages) Datacenter IPs blocked by default Behavioral analysis Mouse events, scroll timing Only triggers on JS-heavy category pages CAPTCHA hCaptcha Triggered on rapid listing traversal The TLS fingerprint check is the highest-priority hurdle. Plain
requestswith a spoofed User-Agent still fails because the TLS handshake looks like Python. Usecurl_cffiwithimpersonate="chrome120"or route through a residential proxy with its own TLS termination.DataDome is the persistent layer. It tracks request cadence across sessions and will silently serve degraded HTML (no badge data, no review count) long before it serves a hard block. This is similar to the detection stack you encounter when doing more general marketplace work like scraping Walmart Marketplace seller data.
Scraping Best-Seller Listings: Working Approach
For listing-level data, the most reliable path in 2026 is:
- Build a seed URL list from Etsy search (
/search?q=)&explicit=1&ship_to=US - Paginate through results pages (up to page 250, ~6000 results per query)
- For each listing URL, fetch the product page and parse the embedded
block - Supplement with HTML parsing for the bestseller badge
import re, json from curl_cffi import requests as cffi_requests SESSION = cffi_requests.Session(impersonate="chrome120") def fetch_listing(url: str) -> dict: resp = SESSION.get( url, headers={ "Accept-Language": "en-US,en;q=0.9", "Referer": "https://www.etsy.com/search", }, timeout=20, ) html = resp.text # Extract JSON-LD match = re.search(r'<script type="application/ld\+json">(.*?)</script>', html, re.S) data = json.loads(match.group(1)) if match else {} # Bestseller badge is_bestseller = 'wt-badge--small' in html and 'Bestseller' in html return { "name": data.get("name"), "price": data.get("offers", {}).get("price"), "rating": data.get("aggregateRating", {}).get("ratingValue"), "review_count": data.get("aggregateRating", {}).get("reviewCount"), "is_bestseller": is_bestseller, }Run this through a rotating residential proxy pool. Aim for one request every 3-8 seconds per IP, randomized. At 10 concurrent sessions across different IPs you can pull roughly 1,500 listings per hour without triggering DataDome's behavioral thresholds.
For tags, fetch the individual listing URL and parse the
elements inside theblock that follows the "Explore related searches" heading. Tags are not in the JSON-LD, only in the HTML.Pulling Trending Tags from the Autocomplete API
The autocomplete endpoint is the fastest source for trending tag signals:
GET https://www.etsy.com/api/v3/ajax/typeahead/etsy/term?term=<prefix>&limit=10No auth required, but you need to set
x-csrf-tokenandx-etsy-user-agentheaders that match a real browser session. Capture these once via browser DevTools, then reuse them. The token rotates every ~24 hours, so build a refresh mechanism.Response includes
results[].termstrings ranked by Etsy's internal trending score. Prefix-sweep common root terms ("handmade", "vintage", "personalized", "custom", "boho") to map the trending tag graph across a category. A full sweep of 200 seed prefixes takes about 15 minutes and produces a clean list of ~800 high-signal tags.This approach is lighter-weight than scraping full search result pages. If you are already running scraping pipelines against other platforms, the session-header management pattern here is similar to what you need for scraping Lever and Greenhouse job boards, where CSRF tokens and session cookies also need active management.
Proxy and Infrastructure Choices
Residential proxies are non-negotiable for Etsy at any meaningful scale. Datacenter IPs are blocked at the DataDome layer. Here is a quick comparison of realistic options:
Provider type Pass rate on Etsy Cost per GB Best for Residential rotating ~85-90% $3-$8 High-volume listing crawls Mobile (4G LTE) ~95%+ $15-$25 Autocomplete API, badge extraction ISP/static residential ~80-85% $4-$10 Session-persistent flows Datacenter <20% $0.50-$2 Not viable for Etsy Mobile proxies outperform residential for Etsy because mobile IPs score well on Etsy's trust model. If you are running similar scraping work on other high-trust-requirement targets like Amazon brand registry pages, the same mobile proxy pool carries over cleanly.
Rotate IPs per domain session, not per request. DataDome penalizes rapid IP rotation more than steady moderate-volume sessions. One IP, one Etsy session, 50-100 requests, then rotate.
Handling Blocks and Soft Failures
Etsy soft-blocks look like real responses. You will get HTTP 200 with stripped content. Build explicit validation:
- Badge count in response should be non-zero if you are querying a bestseller-focused search
- JSON-LD block should always be present on listing pages (its absence = soft block)
- Review count
0on a listing with 4.8 stars is a signal you got served degraded HTML
When you detect a soft block, discard the IP, add a 30-second delay, and retry on a new session. Do not retry the same URL immediately on the same IP. Log soft-block rate per proxy provider to tune your rotation strategy.
The general discipline here applies across scraping targets. When you hit dynamic sites like boutique recruitment portals you see the same pattern: HTTP 200 with missing data fields is often more dangerous than an explicit 403, because it silently corrupts your dataset.
For the full picture on Etsy's data model including seller-level metrics and shop statistics, the Etsy product and seller data scraping guide on DRT covers the shop endpoint structure and pagination in detail.
Bottom line
Use
curl_cffiwith Chrome impersonation, residential or mobile proxies rotated at the session level, and validate every response for soft-block signals before writing to your dataset. The autocomplete API is the fastest route to trending tag data and worth hitting separately from the listing crawl. DRT covers this category of scraping target in depth, so check back as Etsy's detection stack evolves through 2026.Related guides on dataresearchtools.com
How to Scrape Walmart Marketplace Seller Data (2026)
Walmart Marketplace has grown to over 100,000 active third-party sellers, and scraping that seller data — store names, ratings, fulfillment types, product counts, pricing — is increasingly valuable for competitive intelligence, supplier research, and brand monitoring. The challenge is that Walmart’s anti-bot stack has matured considerably in 2025-2026, making naive scrapers fail within minutes.
What Walmart Seller Data Actually Looks Like
Walmart exposes seller data in two main places: the seller storefront page (
walmart.com/seller/) and individual product listing pages where seller info appears in the “Sold by” widget. Each source gives you different fields.Storefront pages yield:
- Seller display name and seller ID
- Aggregate rating and review count
- “Pro Seller” badge status
- Ship speed metrics (1-day, 2-day percentage)
- Product count estimate
Product listing pages give you the seller ID, name, fulfillment type (Walmart Fulfillment Services vs. merchant-fulfilled), and the “Ships from” location. For bulk data collection, product pages are higher-volume but less structured.
Walmart’s seller ID is the anchor. Once you have it, you can cross-reference listings, monitor new SKUs, and track rating drift over time.
Walmart’s Anti-Bot Stack in 2026
Walmart runs Akamai Bot Manager on most crawlable surfaces, with additional JavaScript fingerprinting on seller storefronts. You will see three failure modes:
Response Meaning Fix 403 + Reference #...Akamai hard block Rotate IP + fresh TLS fingerprint 200 + CAPTCHA HTML Akamai challenge page Headless browser with stealth mode 200 + empty seller grid JS-rendered content not executed Switch to full render or extract JSON-LD 429 with Retry-AfterRate limit hit Back off 30-60s, reduce concurrency The most common mistake is treating a 200 response as a success. Walmart frequently returns challenge pages with HTTP 200. Always check the response body for
or the Akamai reference string before parsing.Access Denied Residential proxies outperform datacenter IPs significantly here. Akamai’s scoring model weighs ASN reputation heavily, and datacenter ranges from AWS or GCP get flagged on the first request. Mobile IPs perform best on seller storefronts because Walmart’s primary traffic skews mobile.
Extraction Approach: JSON-LD First, DOM Second
Walmart embeds structured product and seller data in
blocks on listing pages. This is far more stable than CSS selectors, which break on every front-end deploy.import httpx import json from bs4 import BeautifulSoup def extract_seller_from_listing(url: str, proxies: dict) -> dict: headers = { "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15", "Accept-Language": "en-US,en;q=0.9", } r = httpx.get(url, headers=headers, proxies=proxies, timeout=15) soup = BeautifulSoup(r.text, "html.parser") # Extract embedded JSON state -- more reliable than JSON-LD on Walmart for script in soup.find_all("script", {"id": "__NEXT_DATA__"}): data = json.loads(script.string) seller = data["props"]["pageProps"]["initialData"]["data"]["idmlMap"] return { "seller_id": seller.get("sellerId"), "seller_name": seller.get("sellerDisplayName"), "fulfillment_type": seller.get("fulfillmentType"), } return {}The
__NEXT_DATA__script tag is more reliable than JSON-LD on Walmart specifically because it contains the full hydration payload including seller metadata. This pattern holds as of early 2026 but monitor it -- Walmart has migrated page sections incrementally.For storefront pages, the seller rating and product count are rendered client-side via a GraphQL request to
graph.walmart.com. You can intercept this with a headless browser or replay it directly once you have a valid session cookie.Scaling the Crawl
Building a queue-based crawler with respectful concurrency keeps you under the radar longer than aggressive parallelism.
- Seed with Walmart category pages to collect product URLs
- Extract seller IDs from product pages (fast, lightweight)
- Deduplicate seller IDs and queue storefront fetches separately
- Use a 2-5 second random delay between storefront requests per proxy
- Rotate proxies every 50-100 requests or on first 403
- Store raw HTML alongside parsed data for re-parsing without re-fetching
For category seeding, Walmart's department browse pages paginate via
?page=Nand cap at around 25 pages per category. Each page lists 40 products. That gives you roughly 1,000 product URLs per category pass, which is enough to surface 200-400 unique sellers per category.This kind of tiered seller ID collection is similar to what you'd build for How to Scrape Amazon Best Sellers Across 18 Marketplaces (2026) -- seed from rankings, then fan out to seller profiles. The pattern translates directly.
Proxy and Tool Selection
Not all residential proxy providers handle Akamai-protected targets equally. Here's a practical comparison for Walmart specifically:
Provider IP Type Walmart Pass Rate Price/GB Notes Bright Data Residential + Mobile ~85% $8.40 Best for storefronts Oxylabs Residential ~78% $8.00 Good category pages Smartproxy Residential ~70% $7.00 Budget option, higher retry rate IPRoyal Residential ~60% $3.50 Works for listing pages Datacenter (any) DC ~20% $0.50-1.00 Not recommended for Walmart Mobile IPs from Singapore or US locations perform best on Walmart's US storefront pages. This is consistent with what we've seen on other marketplace targets -- Etsy, covered in How to Scrape Etsy Product and Seller Data in 2026, shows the same residential-vs-datacenter gap.
For browser automation, Playwright with
playwright-stealthor Camoufox handles Walmart's JS fingerprinting more reliably than Puppeteer in 2026. Set the viewport to a common mobile resolution (390x844) and avoid headless mode detection patches that are already fingerprinted by Akamai.If you are comparing this workflow against a brand monitoring use case on Amazon, the approach for How to Scrape Amazon Brand Registry Public Pages (2026) covers similar seller-identity extraction patterns that are worth reading alongside this guide.
Data Enrichment and Cross-Marketplace Signals
Raw Walmart seller data becomes more valuable when you join it against other sources. Useful enrichment steps:
- Match seller display names against Amazon seller profiles to identify cross-marketplace operators
- Pull seller IDs into a time-series store and track rating velocity and product count growth weekly
- Flag "Pro Seller" badge changes as a signal for operational maturity shifts
- Compare Walmart fulfillment type against Amazon FBA status for the same brand
Etsy sellers expanding into Walmart is a real trend in craft and home goods. The data collection patterns from How to Scrape Etsy Best Sellers and Trending Tags (2026) can feed a brand-matching pipeline that identifies when Etsy-native sellers launch Walmart storefronts.
For the storage layer, a simple Postgres schema with
sellers(seller_id, name, rating, review_count, is_pro, product_count, scraped_at)plus aseller_snapshotstable for historical tracking is sufficient for most use cases. Index onseller_idandscraped_atfor efficient delta queries.If your use case is competitive intelligence for a specific product category, the same browser-based research techniques used in How to Scrape Boutique Recruitment Site Postings (2026) -- rotating sessions, structured extraction, and deduplication -- apply cleanly here.
Bottom Line
For Walmart seller data in 2026, start with
__NEXT_DATA__extraction on product listing pages to collect seller IDs cheaply, then use residential or mobile proxies for storefront deep-dives. Akamai will block datacenter IPs on sight, so don't waste budget there. DRT will keep covering Walmart's anti-bot changes as they roll out -- bookmark this guide and check back after major Walmart front-end releases.Related guides on dataresearchtools.com
How to Scrape Amazon Brand Registry Public Pages (2026)
Amazon Brand Registry exposes a surprisingly rich set of public pages — brand profiles, ASIN ownership claims, and trademark enforcement data — that most scrapers overlook because they assume it’s locked behind seller accounts. it’s not. the publicly accessible portions of Amazon Brand Registry are fair game for competitive intelligence, brand monitoring, and trademark research, and in 2026 the main friction is anti-bot tooling, not authentication.
What data is actually public on Brand Registry
before writing a single line of code, map out what you can and cannot access without logging in.
publicly accessible:
- brand profile pages at
https://brandregistry.amazon.com/brand/... - brand search results (name lookups return basic profile cards)
- ASIN-to-brand ownership associations visible via standard Amazon product pages
- trademark registration status snippets
not public (requires brand owner login):
- enforcement case history
- ASIN violation reports
- brand analytics dashboards
for most competitive intelligence use cases — who owns what brand, which ASINs are under brand protection, how many products a brand has listed — the public layer is enough. if you need deeper seller data, pairing this with How to Scrape Amazon Best Sellers Across 18 Marketplaces (2026) gives you a more complete picture.
Anti-bot posture in 2026
Amazon Brand Registry runs behind AWS WAF and shares fingerprinting infrastructure with the main amazon.com stack. expect:
- TLS fingerprint checks (JA3/JA4 matching)
- canvas and WebGL fingerprinting on brand search pages
- behavioral analysis on repeated brand name lookups
- Cloudflare Turnstile on some regional variants
the good news is that brand profile pages (direct URL hits) are less aggressively protected than search flows. a structured crawl of known brand slugs with proper residential proxies will clear WAF in the vast majority of requests.
approach success rate cost per 1k requests setup effort datacenter proxies 15-30% ~$0.40 low residential rotating 72-85% ~$2.50 medium mobile residential 88-95% ~$6.00 medium headless browser + residential 90-97% ~$9.00 high for a one-time crawl of a few thousand brands, residential rotating is the right tradeoff. for continuous monitoring at scale, mobile proxies justify the cost because re-attempts on blocks eat into any savings from cheaper tiers.
Scraping brand profile pages with Python
direct page scrapes work well for known brand slugs. the pattern is: build a slug list, rotate proxies, parse with lxml.
import httpx from lxml import html import time, random PROXY_POOL = [ "http://user:pass@proxy1.example.com:8080", "http://user:pass@proxy2.example.com:8080", ] HEADERS = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/124.0.0.0 Safari/537.36", "Accept-Language": "en-US,en;q=0.9", "Accept-Encoding": "gzip, deflate, br", } def fetch_brand_page(slug: str) -> dict: url = f"https://brandregistry.amazon.com/brand/{slug}" proxy = random.choice(PROXY_POOL) with httpx.Client(proxies=proxy, headers=HEADERS, timeout=15) as client: r = client.get(url) if r.status_code != 200: return {"slug": slug, "error": r.status_code} tree = html.fromstring(r.content) brand_name = tree.xpath('//h1[@class="brand-name"]/text()') asin_count = tree.xpath('//span[@data-asin-count]/text()') return { "slug": slug, "brand_name": brand_name[0] if brand_name else None, "asin_count": asin_count[0] if asin_count else None, } slugs = ["brand-slug-1", "brand-slug-2"] for s in slugs: print(fetch_brand_page(s)) time.sleep(random.uniform(1.5, 3.5))a few notes on this pattern: the XPath selectors above are illustrative — Brand Registry page structure changes. always inspect the live DOM before finalising selectors. add a
Referer: https://www.amazon.com/header to mimic organic navigation. and rotate user agents across a set of real Chrome versions, not a static string.Building the brand slug list
this is the hard part. Brand Registry doesn’t expose a public sitemap, so you need to generate the slug list from external sources.
- start with your existing competitor ASIN list and hit
https://www.amazon.com/dp/{ASIN}— the brand name in the product detail page maps to a slug - extract the brand link from the detail page breadcrumb (it routes through
/stores/or/brand/paths) - normalise: lowercase, replace spaces with hyphens, strip special characters
- deduplicate across ASINs — one brand may appear across hundreds of ASINs
for category-scale brand discovery, pull from an Amazon Best Sellers page for your target categories and collect brand names from the product cards before starting the Brand Registry crawl. the slug format is usually the brand name lowercased with hyphens, but Amazon occasionally uses internal IDs, so always validate before bulk queuing.
this upstream data collection problem is similar to what you’d face scraping other large platforms — the How to Scrape Walmart Marketplace Seller Data (2026) guide covers a comparable slug-reconstruction approach for Walmart seller profiles.
Handling errors and rate limits
Brand Registry will return several non-200 responses you need to handle explicitly:
- 403: IP flagged or fingerprint mismatch — rotate proxy and retry after 60s minimum
- 429: explicit rate limit — back off exponentially, minimum 5 minutes
- 503: WAF challenge or origin overload — treat as soft block, retry with fresh session
- 302 to login page: URL requires authentication — you’ve hit a non-public path, adjust your slug
build a dead-letter queue for 403s and 429s rather than dropping them. many of these resolve on retry from a different proxy. for a brand monitoring pipeline running daily, a 5-10% retry rate is normal and acceptable — if you’re above 25%, your proxy pool is either too small or not genuinely residential.
the error-handling patterns here apply broadly to any large-platform scrape. if you’re also pulling from job board infrastructure, How to Scrape Taleo Career Sites at Scale (2026) covers a similar retry architecture for ATS platforms that use comparable WAF setups.
Storing and enriching Brand Registry data
once you have clean brand records, a few enrichment steps significantly increase the dataset’s value:
- join on trademark registration numbers against USPTO TESS (public API, no key needed)
- cross-reference brand names against marketplace seller IDs using the Amazon SP-API (requires seller account but the brand linkage is public)
- append ASIN count trend data by re-crawling on a weekly cadence and diffing
for the storage layer, PostgreSQL with a
brandstable and abrand_snapshotstable for historical diffs is straightforward. index onbrand_slugandcrawled_at. if you’re building a broader competitive dataset that includes marketplace-wide seller and product data, How to Scrape Etsy Best Sellers and Trending Tags (2026) has a compatible schema pattern worth adapting.for teams building out full B2B data pipelines where brand ownership, corporate hierarchy, and contact enrichment all need to connect, the approach described in How to Scrape ZoomInfo Without Account: Public Data Strategies (2026) covers the entity-resolution layer that ties brand data to company records.
Bottom line
scraping Amazon Brand Registry public pages is tractable in 2026 if you use residential proxies, respect the distinction between public and authenticated paths, and build retry logic for the 403/429 responses you will definitely see. start with a targeted slug list derived from your existing ASIN data rather than attempting broad discovery crawls, which attract more aggressive fingerprinting. for ongoing coverage of scraping techniques across major platforms and data sources, DRT publishes updated guides as anti-bot infrastructure evolves.
Related guides on dataresearchtools.com
- How to Scrape Taleo Career Sites at Scale (2026)
- How to Scrape Amazon Best Sellers Across 18 Marketplaces (2026)
- How to Scrape Walmart Marketplace Seller Data (2026)
- How to Scrape Etsy Best Sellers and Trending Tags (2026)
- Pillar: How to Scrape ZoomInfo Without Account: Public Data Strategies (2026)
How to Scrape Amazon Best Sellers Across 18 Marketplaces (2026)
Amazon Best Sellers data is one of the most commercially valuable signals in e-commerce intelligence, and scraping it across all 18 active Amazon marketplaces is harder than it looks. Each locale runs on a separate domain, uses localized anti-bot fingerprinting, and has its own ASIN catalog — meaning a scraper that works on amazon.com will fail silently on amazon.co.jp or amazon.com.br within hours.
What You’re Actually Scraping
Amazon Best Sellers pages follow a predictable URL pattern:
https://www.amazon.{tld}/Best-Sellers/{category}/zgbs/{node_id}Each page returns up to 50 ranked ASINs per category node, paginated across two pages (1-50, 51-100). The data you want per ASIN:
- Rank (1-100 within node)
- ASIN and product title
- Price (locale currency)
- Star rating and review count
- Sponsored flag (boolean — many scrapers miss this)
- Badge labels (“Amazon’s Choice”, “#1 New Release”)
The sponsored flag matters. Best Sellers pages increasingly mix organic rank with promoted listings, and conflating them will corrupt your rank-tracking dataset.
The 18 Marketplace Map
Amazon operates 18 public-facing marketplaces as of 2026. Not all are equal in scraping difficulty:
Marketplace TLD Anti-bot Tier Requires Local IP US .com High No (but helps) UK .co.uk High No Germany .de High No Japan .co.jp Very High Yes India .in Medium No Brazil .com.br Medium Yes Mexico .com.mx Medium No Australia .com.au Medium No Canada .ca High No France .fr High No Italy .it Medium No Spain .es Medium No Netherlands .nl Medium No Sweden .se Low No Poland .pl Low No Saudi Arabia .sa Low No UAE .ae Low No Singapore .sg Low No Japan and Brazil are the two that will block you fastest without residential or mobile IPs from the target country. Japan specifically rate-limits aggressively and serves CAPTCHAs within 3-5 requests if you’re on a datacenter IP.
Parsing Strategy: HTML vs. SP-API vs. Third-Party
You have three realistic options:
- Direct HTML scraping — highest fidelity, most fragile, requires proxy rotation and browser fingerprinting
- Amazon SP-API (Selling Partner API) — structured data, but requires an active seller account and doesn’t expose Best Sellers rank cleanly across all nodes
- Third-party aggregators (Rainforest API, Keepa, DataForSEO) — easiest to operationalize, costs $0.002-$0.02 per ASIN depending on freshness
For competitive intelligence at scale, direct HTML scraping with a rotating proxy layer gives you the freshest data and the widest node coverage. SP-API is better for sellers who need their own rank tracking tied to inventory operations.
If you’re already running proxy-dependent scrapers for other targets — like scraping Walmart Marketplace seller data — you can reuse that infrastructure directly. The same rotating IP pool, session management logic, and retry handlers transfer cleanly.
The Anti-Bot Stack You’ll Actually Face
Amazon runs a layered defense in 2026:
- TLS fingerprinting via BoringSSL — curl and requests fail on most locales without a matching TLS profile
- Browser fingerprint checks (canvas, WebGL, font enumeration) on JavaScript-rendered pages
- Behavioral analysis — consistent timing patterns trigger blocks faster than random delays
- Geographic IP scoring — datacenter ASNs get a higher suspicion score than residential
The practical fix: use a headless browser (Playwright with stealth patches) or a dedicated scraping browser like Browserless or Apify Actors, combined with residential or mobile proxies. For Japan and Brazil specifically, you need in-country mobile IPs. The same logic applies when scraping other commerce platforms with geo-restricted pricing — mobile proxies used for insurance quote comparison demonstrate this pattern clearly: local mobile IP plus rotating session equals consistent access.
A minimal Playwright config for Amazon scraping:
from playwright.async_api import async_playwright async def scrape_best_sellers(url: str, proxy: dict) -> str: async with async_playwright() as p: browser = await p.chromium.launch( proxy=proxy, args=["--disable-blink-features=AutomationControlled"] ) ctx = await browser.new_context( user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", locale="en-US", timezone_id="America/New_York", ) page = await ctx.new_page() await page.goto(url, wait_until="domcontentloaded") content = await page.content() await browser.close() return contentSet
localeandtimezone_idto match the target marketplace country, not your proxy IP’s country. Mismatches are a detectable signal.Structuring a Multi-Marketplace Pipeline
Running 18 markets in parallel is the right architecture, but naive parallelism gets you blocked. The structure that works:
- One session pool per marketplace — don’t reuse US session cookies on .co.uk
- Stagger requests per node — 2-5 second jitter between category pages within a single market
- Checkpoint by ASIN hash — if a page returns fewer than 40 ASINs, treat it as a soft block and retry with a fresh session, not the same one
- Deduplicate sponsored ASINs — store a
is_sponsoredboolean at ingest, filter downstream
For the data model, store raw HTML in object storage (S3/R2) and parse to structured rows separately. Amazon’s HTML structure changes without notice; having the raw payload means you can re-parse without re-scraping.
This pipeline architecture is similar to what you’d build for ATS platform scraping at scale — the same session isolation and checkpoint logic that makes iCIMS career site scraping and Taleo scraping at scale reliable also applies to marketplace data pipelines. The underlying problem — maintaining session integrity across distributed workers — is the same class of challenge.
For brand-level research, Best Sellers data pairs well with Amazon Brand Registry public page data, which gives you trademark registration dates and brand owner identities to enrich your ASIN-level records.
Handling Failures at Scale
Common failure modes and how to handle them:
- 503 / captcha page returned as 200 — parse response body for
containing “Robot Check” before processing - Redirect to signin page — session expired; rotate to fresh session, do not retry same credentials
- Missing rank badges — normal on low-traffic nodes; don’t treat as parse failure
- Price not rendered — JavaScript-dependent; ensure page fully loads before extracting, or use
wait_for_selectoron the price element
Rate your proxy health by marketplace separately. A proxy pool that performs well on amazon.com can be effectively blocked on amazon.co.jp. Monitor block rates per
(proxy_asn, marketplace)tuple and drop underperforming ASNs from that market’s pool automatically.Bottom Line
Scraping Amazon Best Sellers across 18 marketplaces is tractable in 2026 if you treat each locale as a separate target with its own proxy pool, session state, and block-rate monitoring. The two non-negotiables: residential or mobile IPs for Japan and Brazil, and a browser fingerprint that doesn’t expose automation. DRT covers the full stack of e-commerce and job board scraping infrastructure — if this article was useful, the rest of the scrape-target library will be too.
Related guides on dataresearchtools.com
Proxy Patterns for App Store Position Tracking (2026)
App store position tracking without proxies is broken by design. The App Store and Google Play serve different rankings based on country, device type, and even carrier — and if your scraper runs from a single datacenter IP, you’re getting one slice of a highly localized picture. Getting this right in 2026 means matching your proxy infrastructure to the way app store crawlers get blocked, rate-limited, and fingerprinted.
Why App Store Ranking Data Is Harder to Collect Than It Looks
Apple and Google both serve ranking data dynamically. A top-10 result for “expense tracker” in the US App Store differs from the same query in Singapore or Germany — and those differences update hourly during peak periods. The naive approach (curl from an AWS instance) gets you either a CAPTCHA wall or stale cached data within minutes.
The core problem is that app store endpoints use a combination of IP reputation scoring, request-rate fingerprinting, and geo-validation. Datacenter IPs are flagged almost immediately. Even well-known residential proxy pools with large subnets get rate-limited once they show consistent scraping patterns.
This is a structural problem, not a solvable-with-headers one. The fix is at the proxy layer, not the request layer.
Proxy Type Selection: Mobile First, Residential Second
For app store rank tracking specifically, mobile proxies outperform residential on every dimension that matters:
Proxy Type Trust Score Geo Accuracy Cost/GB Block Rate (App Stores) Datacenter Low Medium $0.50-1 Very high Residential Medium High $3-8 Medium Mobile (4G/5G) Very high Very high $8-20 Low ISP (static res.) Medium-high High $4-10 Medium Mobile IPs are assigned by carriers and rotate through CGNAT pools — the same infrastructure a real iPhone uses to browse the App Store. That’s exactly the signal app store anti-bot systems look for. The same logic applies to proxy selection for ticket bots, where trust-tier matching between proxy and platform determines whether you get real data or a block.
For rank tracking at scale across 10+ countries, you need country-matched mobile IPs. A Singapore mobile IP hitting the SG App Store will behave like a local user. A US residential IP doing the same thing may work but will show higher block rates over time, particularly for keyword search ranking endpoints.
Rotation Strategy: Request-Level vs. Session-Level
How you rotate matters as much as which proxy type you use. App store ranking checks fall into two patterns:
Request-level rotation (new IP per request) works for:
- Top charts by category
- Featured app lists
- Search result pages (non-personalized)
Session-level rotation (same IP for a sequence of requests) works for:
- Keyword ranking checks that require simulating a search + scroll + click flow
- A/B test visibility sampling
- Store listing page reads with embedded review counts
For session-level work, you want sticky sessions of 2-5 minutes per IP. Most mobile proxy providers support session tokens or sticky endpoints — use them. If you’re running parallel country checks, assign one sticky session per country per keyword batch.
This is the same session discipline that matters in proxy patterns for brand protection monitoring, where per-platform session consistency prevents false negatives from mid-session IP switches.
Building a Rank Tracking Scraper: Minimal Working Config
A basic Google Play rank tracker in Python using a rotating mobile proxy:
import httpx import time PROXY = "http://user-country-us-session-kw001:pass@mobile.proxypool.io:8080" def check_play_rank(keyword: str, app_id: str) -> int | None: url = "https://play.google.com/store/search" params = {"q": keyword, "c": "apps", "hl": "en", "gl": "US"} headers = { "User-Agent": "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36", "Accept-Language": "en-US,en;q=0.9", } try: r = httpx.get(url, params=params, headers=headers, proxies={"https://": PROXY}, timeout=15) r.raise_for_status() # parse position of app_id from result HTML return parse_rank(r.text, app_id) except httpx.HTTPStatusError as e: if e.response.status_code == 429: time.sleep(30) return NoneKey decisions in this config: Android UA paired with a mobile proxy (consistent fingerprint), session token in the proxy auth string for sticky behavior per keyword, and explicit 429 handling before retry. Running this with a datacenter proxy and a desktop Chrome UA is a common mismatch that inflates your block rate for no gain.
Multi-Country Tracking: Geo Assignment and Coverage
Running rank checks across 10+ countries introduces a prioritization problem. Not all markets need the same check frequency. A useful breakdown:
- Tier 1 markets (US, UK, DE, JP, AU) — check every 4-6 hours, mobile proxies required
- Tier 2 markets (SG, FR, BR, CA, KR) — check every 12 hours, residential proxies acceptable
- Tier 3 markets (remaining) — daily checks, ISP proxies usually sufficient
For Tier 1, budget for mobile proxies from carriers that match the market. US AT&T or T-Mobile IPs for the US App Store outperform generic residential on trust scoring. For Tier 2 and below, the cost savings from using residential are meaningful and the block rate difference is tolerable at 12+ hour intervals.
This tiered approach is similar to what proxy patterns for ad verification uses — high-trust proxies for high-value markets, cost-optimized tiers everywhere else.
When you scale past 20 countries, proxy health becomes a real operational concern. Stale IPs, misconfigured sticky sessions, and provider outages will silently corrupt your ranking data. The Build a Proxy Health Monitor guide covers how to build real-time status checks that catch these failures before they become data quality problems.
Common Failure Modes and Fixes
- Silent 200s with bad data: App stores sometimes return a 200 with a CAPTCHA page or empty results. Always validate that the response contains expected app count or known app IDs.
- Geo mismatch: Your proxy reports US location, but the App Store serves UK results. Verify geo assignment by hitting an IP-check endpoint before each session batch.
- Rate limit drift: Block rates increase gradually over days, not immediately. Monitor your 429 rate on a rolling 24-hour window, not just current session.
- UA inconsistency: Mobile proxies with desktop UAs get higher scrutiny. Match Android/iOS UA to mobile proxy type.
The proxy selection guide for sneaker bots has a useful breakdown of fingerprint consistency requirements that applies directly here — the same platform-signal matching logic that works for checkout flows works for app store API calls.
Bottom line
For app store position tracking in 2026, use mobile proxies for Tier 1 markets, session-level rotation for keyword flows, and a tiered geo strategy to keep costs in check without sacrificing data quality. Validate response content — not just status codes — at every step. DRT covers proxy infrastructure patterns like these in depth; if you’re building a tracking pipeline from scratch, the health monitoring and proxy selection guides are the right starting points before you write a line of scraping code.
Related guides on dataresearchtools.com
- Proxy Patterns for Ad Verification at Scale (2026)
- Proxy Patterns for Brand Protection Monitoring (2026)
- Proxy Selection for Sneaker Bots in 2026: Mobile vs ISP vs Residential
- Proxy Selection for Ticket Bots: Why Residential Wins (2026)
- Pillar: Build a Proxy Health Monitor: Real-Time Status Tracking
Proxy Patterns for Brand Protection Monitoring (2026)
Brand protection monitoring is one of the few scraping use cases where getting caught isn’t just inconvenient — it’s catastrophically bad for the data. Counterfeit listings disappear, grey-market sellers rotate domains, and unauthorized resellers swap pricing the moment they detect a crawler. Proxy patterns for brand protection monitoring have to be built around stealth, geographic precision, and high rotation frequency, or the data you collect is already stale by the time it lands in your pipeline.
Why Standard Residential Proxies Fall Short
Most brand protection teams start with a residential proxy pool and call it done. That works for basic price monitoring, but it breaks down fast when you need to:
- Detect unauthorized resellers across 15+ marketplaces simultaneously
- Verify geo-restricted counterfeit listings that only surface in specific countries
- Monitor social commerce platforms (TikTok Shop, Instagram Shopping) that fingerprint proxy ASNs aggressively
- Catch trademark violations on ad networks that rotate creatives by IP geolocation
Residential proxies from large pools (Bright Data, Oxylabs, Smartproxy) share exit IPs across thousands of customers. A single IP used for scraping Amazon one hour and brand-checking Shopify the next carries cross-contamination risk. Platforms that flag scraper IPs share blocklists — your “clean” residential IP may already be poisoned before you use it.
The better approach is proxy segmentation by platform tier.
Proxy Type Selection by Platform Tier
Not every marketplace deserves the same proxy budget. Tier your infrastructure to match detection sophistication:
Platform Type Recommended Proxy Rotation Frequency Typical Cost Amazon, eBay, Walmart Mobile (4G/5G) Per request $8-15/GB Shopify storefronts ISP residential Per session (5-10 min) $2-4/GB Social commerce (TikTok Shop) Mobile with sticky sessions Per product page $10-20/GB Brand registry portals Datacenter (authenticated) Per login session $0.10-0.50/GB Telegram/Discord grey markets SOCKS5 mobile Per conversation thread $12-18/GB Mobile proxies outperform residential for high-value targets because they present real carrier ASNs (Singtel, Verizon, EE) rather than ISP ranges that platforms have learned to profile. For the same reason they dominate in proxy selection for sneaker bots — the underlying fingerprint logic is identical: platforms want to see a real device on a real carrier network.
Geographic Targeting and the Country-IP Mismatch Problem
Counterfeit goods listings are often geo-fenced. A fake luxury handbag listing on a Southeast Asian marketplace may never appear to a US IP. Your monitoring stack has to request pages from within the target country, not from a proxy provider’s nearest PoP.
The critical mistake is using a provider’s “country targeting” feature without verifying actual exit geography. Many residential pools label IPs by billing country, not by where the device physically connects. Run a validation sweep before any monitoring campaign:
import httpx import asyncio async def verify_exit_geo(proxy_url: str, expected_country: str) -> dict: async with httpx.AsyncClient(proxies={"all://": proxy_url}, timeout=10) as client: r = await client.get("https://ipapi.co/json/") data = r.json() return { "proxy": proxy_url, "actual_country": data.get("country_code"), "asn": data.get("org"), "match": data.get("country_code") == expected_country } # Run against your pool before campaign launch results = asyncio.run(asyncio.gather(*[ verify_exit_geo(p, "SG") for p in proxy_pool[:50] ])) mismatches = [r for r in results if not r["match"]] print(f"{len(mismatches)} geo mismatches out of 50 sampled")In practice, 10-25% of “country-targeted” residential IPs fail this check with budget providers. For brand monitoring campaigns tied to specific markets (EU luxury goods enforcement, SG parallel imports), this mismatch rate produces false negatives — you conclude a listing doesn’t exist because your IP was routed through a different country.
Session and Fingerprint Management
Brand protection crawls have a different session lifecycle than standard price scrapers. You’re not just fetching a product page — you’re often navigating seller profiles, clicking through to contact pages, and capturing screenshots for legal evidence.
Key session rules:
- Bind one IP to one seller investigation workflow from start to finish. Never rotate mid-session on a seller profile page.
- Use browser-level fingerprinting (Playwright with real Chrome, not httpx) for any platform that serves React or Next.js storefronts.
- Set realistic viewport, locale, and timezone headers that match the exit IP’s country.
- Add 2-8 second jitter between page transitions — brand protection crawls are slower than price scrapers because the evidence chain matters.
- Archive full HTTP response headers alongside screenshots for legal defensibility.
This is the same session discipline required in ad verification at scale, where a session that switches IPs mid-audit produces evidence that opposing counsel can challenge in court.
Marketplace-Specific Patterns
Amazon Brand Registry Monitoring
Amazon’s Brand Registry portal itself uses authenticated sessions, so datacenter proxies are fine there. The risk surface is the public marketplace, where you’re scraping ASIN pages to detect unauthorized third-party sellers. Use residential or ISP proxies per ASIN batch, and rotate after every 15-20 requests per IP.
Watch for Amazon’s “dogs of war” pattern: they serve honeypot ASINs to scrapers with slightly wrong pricing data. If your monitoring pipeline shows wildly inconsistent prices that don’t match manual checks, you’re likely getting served poisoned responses.
App Store and Social Platform Monitoring
App store brand monitoring (fake apps impersonating your brand) uses a different proxy pattern to what’s needed for position tracking — you’re not tracking rank, you’re doing bulk search sweeps for trademark variations. Mobile proxies with country rotation work best here because Apple and Google serve different search results by device locale, not just IP geolocation.
Affiliate and Reseller Channel Audits
Unauthorized affiliate channels are the hardest to catch because they’re often behind branded subdomains or redirect chains. The scraping pattern has to follow the full redirect chain before rendering. A proxy that blocks CONNECT tunneling will silently drop the affiliate referral parameter, giving you a false “clean” result. This overlaps with the challenge covered in affiliate network validation — the proxy stack has to preserve redirect fidelity end to end.
Building a Rotation Architecture That Holds Up
A solid brand protection proxy architecture follows the same layered design as any serious scraping system. The proxy server architecture patterns guide covers the component breakdown in depth, but for brand protection the critical additions are:
- Evidence archiving layer: every request that captures a counterfeit listing must log the full response, exit IP, timestamp (UTC), and geo verification result. Store this in append-only object storage, not a mutable database.
- Dedup by seller fingerprint, not URL: the same counterfeit seller will rotate product URLs. Your dedup key should be seller ID + marketplace, not listing URL.
- Separate pools for evidence capture vs. discovery: use cheap residential for broad discovery sweeps, reserve mobile IPs for the evidence capture requests you’ll present to brand registry or legal counsel.
Failing to separate these pools is expensive. Mobile proxy bandwidth at $12-18/GB burns fast when you’re doing discovery sweeps across thousands of search queries. Keep mobile strictly for the 5-10% of findings that need defensible screenshots.
Bottom Line
For brand protection monitoring in 2026, use mobile proxies for evidence capture on tier-1 marketplaces, ISP residential for session-heavy storefronts, and datacenter only for authenticated brand registry portals. Always geo-verify your exit IPs before campaign launch — mislabeled country pools are the single biggest source of false negatives. DRT covers proxy infrastructure patterns for these exact production use cases, and the tradeoffs here hold across every marketplace vertical where legal defensibility of the captured data actually matters.
Related guides on dataresearchtools.com
Proxy Patterns for Continuous SEO Rank Tracking 2026: Cost vs Coverage
Continuous SEO rank tracking is deceptively expensive at scale. Pull 500 keywords across 10 locales daily and you are firing 5,000 requests every 24 hours — enough to trigger Google’s bot detection within minutes unless your proxy layer is designed for it. The proxy patterns for SEO rank tracking in 2026 are not the same ones you would use for e-commerce or social scraping, and the cost-vs-coverage tradeoff is sharper than most teams realize when they first spec out a tracker.
Why SEO Rank Tracking Has Unique Proxy Requirements
Google SERPs are the most aggressively defended scrape target on the web. Cloudflare, reCAPTCHA v3, and Google’s own fingerprinting stack all run in parallel. The failure mode is not a 403 — it is a degraded SERP that looks real but returns a CAPTCHA page or a country-mismatch result, silently poisoning your rank data.
The requirements that follow from this:
- Residential or mobile IPs only. Datacenter ranges are blocked or heavily throttled on Google Search within hours of high-volume use.
- Geo-matched IPs. A Singapore IP returning results for a UK keyword query will pull a geo-biased SERP. You need IPs in the same city or region as your target locale.
- Low request rate per IP. Google’s session model tolerates roughly 3-5 SERP requests per IP per hour before score degradation. Burst above that and you burn the IP.
- Consistent User-Agent + cookie jar pairing. Rotating UA without rotating cookies (or vice versa) creates a fingerprint mismatch that triggers detection faster than either alone.
Proxy Type Comparison: Residential vs Mobile vs ISP
Not all residential proxies behave the same way for rank tracking. Here is how the main categories compare in 2026 practice:
Type Pass Rate (Google) Cost per GB Best Use Case Residential rotating ~85-92% $3-8 Broad keyword sets, multi-locale Mobile (4G/5G) ~96-99% $12-25 High-value keywords, local packs ISP (static residential) ~88-94% $2-5 Consistent session tracking Datacenter ~30-55% $0.20-0.80 Not recommended for Google SERPs Mobile proxies have the highest pass rates because the IP ASN maps to a carrier, not a hosting provider, but the cost is 3-5x residential. The practical split most teams land on is mobile for the top 10-20% of keywords by revenue importance, and residential rotating for the long tail. If you are also running ad verification workflows, the same mobile pool can pull double duty — this overlap is discussed in Proxy Patterns for Ad Verification at Scale (2026).
Request Scheduling: The Architecture That Determines Cost
The biggest cost lever is not which proxy provider you pick — it is how you schedule requests. Naive rank trackers fire all keywords in parallel bursts at the same time each day. This maximizes IP burn rate and forces you to buy more bandwidth to compensate.
A better pattern:
- Spread requests across a 6-hour window. Pick a window that matches off-peak search activity in your target locale (typically 2am-8am local time). Fewer concurrent queries from the same IP pool means lower per-IP load.
- Group keywords by locale first, then by query intent. Brand keywords, local pack queries, and informational queries hit different SERP layouts. Grouping them lets you reuse the same proxy session for similar fingerprint patterns.
- Implement exponential backoff on 429s, not just retries. A flat retry loop burns IPs. Back off 30s, 2min, 8min before rotating to a fresh IP.
- Cache static SERP elements. Knowledge panels, featured snippets, and “People also ask” boxes change slowly. Pull them once daily at full fidelity, not on every keyword cycle.
A minimal Python scheduler config that applies jitter to avoid predictable timing:
import random, time def throttled_request(session, url, base_delay=12): jitter = random.uniform(0.5, 1.8) time.sleep(base_delay * jitter) return session.get(url, timeout=15)The
base_delayof 12 seconds keeps you under 5 requests per IP per hour at a single-thread level. Run 4 threads per proxy session and you hit roughly 20 requests per hour per IP — still within safe range for most residential providers.Locale Coverage Without Breaking the Budget
Multi-locale tracking is where budgets blow up. The temptation is to buy geo-targeted residential pools in every country you track. In practice, most teams only need city-level accuracy for local pack keywords — country-level IPs are sufficient for standard organic rankings.
A tiered coverage model keeps costs manageable:
- Tier 1 (city-level mobile): Primary revenue markets, local pack tracking, Google Maps rank checks
- Tier 2 (country-level residential): Secondary markets, informational keyword monitoring
- Tier 3 (shared rotating residential): Long-tail, low-priority, or experimental keyword sets
For affiliate sites doing competitive rank monitoring across many verticals, this same tiering logic applies to proxy selection decisions more broadly, as covered in Proxy Patterns for Affiliate Network Validation in 2026.
One underused tactic: for locales where you have low keyword volume (under 50 keywords), use a proxy provider’s on-demand geo-targeting rather than a dedicated pool. Providers like Oxylabs, Bright Data, and Smartproxy all support country+city targeting on their rotating residential endpoints with no minimum commitment.
Handling Detection and Result Validation
A proxy that returns a 200 is not the same as a proxy that returned a valid SERP. Google serves different page structures to suspected bots, and if your parser is not validating SERP structure before storing rank data, you are silently ingesting garbage.
Validation checks to run before writing rank data:
- Confirm the
#searchdiv or equivalent organic results container is present - Check that the number of organic results is within expected range (7-10 for standard queries)
- Verify the result URLs are real domains, not redirect traps
- Flag any response where the page title contains “unusual traffic” or CAPTCHA patterns
The same challenge of detecting degraded or fraudulent responses shows up in survey and earn-app proxy setups, where providers serve fake completion pages to suspected automation — Proxy Selection for Survey Sites and Earn Apps (2026) covers that validation pattern in detail.
For video and YouTube SERP tracking, the fingerprinting stack is slightly more lenient than Google Search but locale-matching matters even more because YouTube’s ranking algorithm is heavily localized. If you are tracking video properties alongside web rankings, YouTube SEO and Video Rank Tracking with Proxies (2026) lays out the specific IP requirements for YouTube SERP pulls.
The sneaker-drop proxy community solved rotating IP exhaustion under high detection pressure years before the SEO tracking world caught up — Proxy Selection for Limited Drop Sneaker Releases (2026) has relevant patterns for IP recycling and session warm-up that translate directly to rank tracker architecture.
Bottom Line
For most teams running 500-2,000 keywords daily, the right setup is residential rotating for the long tail plus a small mobile pool for local and high-value terms, with request jitter and SERP validation baked in from day one. Skipping validation is the most common reason rank data becomes unreliable under scale. DRT covers proxy infrastructure and scraping patterns across SEO, ad tech, and data collection — if this architecture is relevant to your stack, the other proxy use-case guides in this series are worth a read.
Related guides on dataresearchtools.com
How to Scrape Taleo Career Sites at Scale (2026)
Oracle Taleo powers job listings for thousands of enterprise employers — Fortune 500s, healthcare systems, government contractors — and scraping it at scale is genuinely harder than scraping most ATS platforms. The challenge is not just pagination; Taleo’s hosted endpoints vary by tenant subdomain, its JavaScript-heavy requisition pages resist simple HTTP fetches, and its rate limiting is aggressive enough to block naive scrapers within minutes.
How Taleo’s Architecture Works (and Why It Matters)
Taleo deployments fall into two patterns. The older “hosted” model puts job listings at a subdomain like
company.taleo.net/careersection/, while newer Oracle Recruiting Cloud (ORC) tenants serve listings underfa-xxxx.oraclecloud.com. Both use server-side rendered pages for the job list but load full requisition details via internal API calls.The key discovery: every Taleo instance exposes a semi-public REST endpoint at
/careersection/rest/jobboard/searchjobs(older hosted) or a GraphQL-style endpoint in ORC. Hitting this directly returns JSON, bypassing HTML parsing entirely and cutting scrape complexity by half.import httpx TENANT = "companyname" BASE = f"https://{TENANT}.taleo.net/careersection/rest/jobboard/searchjobs" params = { "multiln": "false", "lang": "en", "start": 0, "limit": 25, "portal": "1", } headers = { "Accept": "application/json", "Referer": f"https://{TENANT}.taleo.net/careersection/joblist.ftl", } resp = httpx.get(BASE, params=params, headers=headers, timeout=15) data = resp.json() jobs = data.get("requisitionList", [])Increment
startby 25 per page untilrequisitionListis empty. For ORC tenants, the endpoint changes to av2/jobspath — inspect XHR calls in DevTools to find it.Tenant Discovery at Scale
Scraping one company is trivial. Scraping thousands requires a tenant enumeration strategy. There is no official registry, so you build it from:
- LinkedIn job postings that include
taleo.netin the apply URL - Google dork:
site:taleo.net "careersection" "apply now" - Common Crawl extracts filtered by
taleo.nethostnames - Job board APIs (Indeed, ZipRecruiter) that leak the ATS apply URL
Once you have a list of subdomains, check liveness with a HEAD request to
/careersection/joblist.ftl. Expect 10–30% to return 404 (abandoned tenants) or redirect to the parent company’s careers page after an acquisition.If you are scraping Ashby or iCIMS tenants alongside Taleo for a talent pipeline, the same discovery pattern applies — see How to Scrape Ashby Career Sites for Talent Pipelines (2026) for a comparable approach, and How to Scrape iCIMS Career Sites (2026) for iCIMS-specific quirks.
Rate Limiting and Anti-Bot Behavior
Taleo hosted instances run Oracle’s WAF in front of a JBoss application server. The rate limits are tenant-configurable but typical defaults are:
Behavior Threshold Response Rapid sequential requests >10 req/s per IP 429 or silent 503 Missing Referer/Accept headers Any rate 403 Session cookie absence First request Redirect to login ORC tenants (FA-series) >5 req/s per IP Akamai bot challenge The session cookie issue is the most common failure mode. Taleo hosted requires a valid
JSESSIONIDplus aTaleoSIDcookie acquired from the initial page load. The REST endpoint will return a 302 to the login page if these are absent.Fix this by doing a single GET to
/careersection/joblist.ftlbefore hitting the REST endpoint, capturing cookies from the response, and forwarding them on all subsequent requests. Withhttpx, use aClientwith cookie jar enabled:with httpx.Client(follow_redirects=True) as client: client.get(f"https://{TENANT}.taleo.net/careersection/joblist.ftl") # cookies now populated resp = client.get(BASE, params=params, headers=headers)For ORC tenants on Akamai, residential proxies are unavoidable. Datacenter IPs get challenged immediately. The proxy rotation pattern is the same one covered in How Proxies Help Scrape Reviews at Scale: Yelp, Google, Trustpilot (2026) — one IP per session, rotate on 429, minimum 2-second delay between requisition fetches.
Parsing Requisition Detail Pages
The job list API returns metadata (title, location, req ID, posting date) but not the full description. To get the JD body, you need to hit the requisition detail page:
/careersection/10000/jobdetail.ftl?job={reqId}&lang=enThis is an HTML page. The description sits inside a
container. Parse with BeautifulSoup:from bs4 import BeautifulSoup detail_resp = client.get( f"https://{TENANT}.taleo.net/careersection/10000/jobdetail.ftl", params={"job": req_id, "lang": "en"}, ) soup = BeautifulSoup(detail_resp.text, "lxml") desc_div = soup.find("div", id="requisitionDescriptionInterface") description = desc_div.get_text(separator="\n").strip() if desc_div else ""Note: the
10000in the URL is the career section ID, not a real number. Different tenants use different IDs (10000, 10200, 5001, etc.). Check the job list page source for the correct value before scraping.Key fields to extract from detail pages:
- Job title, requisition ID, posting date
- Location (often structured as city, state, country separately)
- Employment type (full-time / contract / internship)
- Department and business unit
- Full JD text (HTML preserved for downstream parsing)
Infrastructure for Multi-Tenant Runs
Running this against hundreds of tenants in parallel requires a queue, not a loop. A simple architecture:
- Queue: Redis or SQS with tenant subdomains as items
- Workers: 4–8 async Python workers per machine, each managing its own httpx
Clientwith cookie jar - Proxy pool: Rotate IPs at the worker level, not per-request. Sticky sessions per tenant reduces cookie re-acquisition overhead.
- Storage: Write raw JSON and HTML to S3 or local disk first, parse separately. Parsing bugs should not require re-fetching.
- Dedup: Hash on
(tenant, reqId)to skip already-seen requisitions on incremental runs.
For comparison, the same async worker pattern applies well when scraping product data at scale — the worker isolation model described here is similar to what you would use for How to Scrape Amazon Best Sellers Across 18 Marketplaces (2026). For brand and company intelligence use cases that combine job data with public registry data, see How to Scrape Amazon Brand Registry Public Pages (2026) for a comparable enrichment workflow.
For incremental runs, check
postingDateagainst your last-seen timestamp per tenant rather than re-fetching the full listing. Most enterprise tenants post under 50 new roles per week, so a daily incremental pull with a 7-day lookback window covers 99% of new postings.Bottom Line
Taleo is scrapeable at scale once you handle the session cookie requirement and split your scrape into a fast list API call plus a slower detail HTML fetch. Target the
/rest/jobboard/searchjobsendpoint first; fall back to HTML parsing only if the tenant blocks it. Use residential proxies for ORC (FA-series) tenants and rate-limit to one requisition fetch every 2–3 seconds per IP. DRT covers patterns like this across the ATS and e-commerce scraping landscape for engineers who need production-grade pipelines, not toy examples.Related guides on dataresearchtools.com
- How to Scrape Ashby Career Sites for Talent Pipelines (2026)
- How to Scrape iCIMS Career Sites (2026)
- How to Scrape Amazon Best Sellers Across 18 Marketplaces (2026)
- How to Scrape Amazon Brand Registry Public Pages (2026)
- Pillar: How Proxies Help Scrape Reviews at Scale: Yelp, Google, Trustpilot (2026)
How to Scrape iCIMS Career Sites (2026)
iCIMS powers career portals for thousands of mid-to-enterprise employers, and scraping it at scale is harder than it looks. The platform serves job listings through JavaScript-rendered pages, enforces bot detection via Cloudflare and custom fingerprinting, and rotates URL structures across tenant subdomains. if you’re building a talent pipeline, competitive intelligence feed, or labor market dataset, here’s what actually works in 2026.
How iCIMS Structures Its Job Data
iCIMS career sites follow a predictable tenant subdomain pattern:
https://{company}.icims.com/jobs/search. each company gets its own subdomain, but the underlying HTML skeleton is consistent across tenants. job detail pages live at/jobs/{job_id}/joband contain the full description, location, department, and requisition metadata in both rendered HTML and a partially-hydrated JSON blob embedded in atag.that structured data block is your fastest extraction path. it follows the
JobPostingschema.org spec and includestitle,hiringOrganization,jobLocation,datePosted, anddescriptionwithout needing a headless browser for the detail page. the search listing page is the hard part -- it's React-rendered and paginated via XHR calls to a private REST API.Reverse-Engineering the Search API
the real extraction leverage comes from the iCIMS job search XHR endpoint, not the DOM. open DevTools on any
{tenant}.icims.com/jobs/searchpage, filter by XHR, and you'll see calls to:GET /jobs/search?ss=1&searchLocation=&searchCategory=&searchZip=&searchRadius=50&searchPositionType=&applyOnline=1&in_iframe=1that endpoint returns paginated JSON with
searchResultscontaining job IDs, titles, locations, and department labels. you can drive pagination withstartrowandmaxrowsparameters (default 10, max 25 per call). extract the IDs, then hit the detail endpoint for full content.import httpx, time TENANT = "yourcompany" BASE = f"https://{TENANT}.icims.com/jobs" def fetch_jobs(start=0, max_rows=25): params = { "ss": 1, "startrow": start, "maxrows": max_rows, "searchPositionType": "", "applyOnline": 1, "in_iframe": 1 } r = httpx.get(f"{BASE}/search", params=params, headers={ "User-Agent": "Mozilla/5.0 (compatible; research-bot/1.0)", "Referer": f"https://{TENANT}.icims.com/jobs/search" }, timeout=15) r.raise_for_status() return r.json() def fetch_detail(job_id): r = httpx.get(f"{BASE}/{job_id}/job", timeout=15) from bs4 import BeautifulSoup import json, re soup = BeautifulSoup(r.text, "html.parser") ld = soup.find("script", {"type": "application/ld+json"}) return json.loads(ld.string) if ld else {}add a 1-2 second delay between requests per tenant. iCIMS rate-limits by IP and will return 429s if you hammer a single subdomain.
Anti-Bot Layers and How to Route Around Them
iCIMS deployments vary in how aggressively they're protected. here's a practical breakdown:
protection layer frequency bypass approach Cloudflare challenge page ~40% of tenants residential proxy + TLS fingerprint match IP rate limiting (429) universal throttle + rotating proxies User-Agent fingerprinting moderate browser-like UA string + accept headers CAPTCHA on search rare (<5%) headless browser + solver Referrer checking common always set Refererto the search pagefor most tenants, httpx with a realistic User-Agent and a proper Referer header is enough. for Cloudflare-protected tenants, you'll need residential IPs. datacenter IPs get challenged or blocked outright on ~40% of iCIMS deployments.
the scraping patterns here are similar to what you'd encounter with How to Scrape Taleo Career Sites at Scale (2026) -- both platforms sit behind enterprise-grade CDN layers with tenant-level variance in protection strictness.
Scaling Across Hundreds of Tenants
scraping one iCIMS tenant is straightforward. scraping 500 of them for a labor market feed requires a different architecture:
- build a tenant discovery list -- iCIMS doesn't publish a directory, but you can source subdomains from job board aggregators, LinkedIn company pages, and certificate transparency logs (
crt.shquery:%.icims.com). - deduplicate subdomains and validate them with a HEAD request before adding to your queue.
- run per-tenant scrapers in parallel, but cap concurrency per IP to 2-3 tenants at a time.
- use a rotating residential proxy pool so each subdomain sees requests from varied IPs. per-tenant sticky sessions for 5-10 minutes prevent cookie invalidation mid-crawl.
- store raw JSON from the search API separately from parsed detail records so you can re-parse without re-fetching.
key fields to extract per job:
job_id,tenant,title,location.city,location.state,location.country,department,employment_type,date_posted,description_html. if you want structured skill extraction, run the raw description through an LLM after collection.for teams building similar pipelines against ATS platforms, the approaches covered in How to Scrape Ashby Career Sites for Talent Pipelines (2026) and How to Scrape Personio Career Sites (2026) show how the same tenant-discovery and schema-extraction pattern generalizes across vendors.
Common Errors and What They Mean
- 429 Too Many Requests -- you're hitting the rate limiter. back off 30-60 seconds, add jitter, reduce concurrency on that tenant.
- 403 Forbidden -- IP is blocked or Cloudflare challenge triggered. rotate to a residential proxy and retry with a fresh session.
- Empty
searchResultsarray -- tenant uses a custom iCIMS build with a different API path. fall back to DOM scraping the listing page directly. - Malformed JSON in ld+json block -- some older iCIMS tenants have invalid JSON in the schema.org tag. use
json.loadsinside a try/except and fall back to BeautifulSoup field extraction. - Redirect to login page -- the job is no longer active. log it as expired and skip.
this error taxonomy overlaps significantly with what you see in other structured-data scraping contexts. if you're also pulling product catalog data, the same proxy rotation and error handling patterns apply in environments like How to Scrape Amazon Best Sellers Across 18 Marketplaces (2026), where IP reputation is equally critical.
one underrated issue: iCIMS occasionally injects a
redirect for bots that don't execute JavaScript. if your scraper returns a page with zero job listings but a valid 200 status, check whether you landed on the noscript fallback. the giveaway is atag in the response body.the same JavaScript-rendering challenge comes up in entirely different verticals -- the JS-heavy listing pages in How to Scrape Latin American Real Estate Sites (Imovelweb, Mercado Libre) use almost identical anti-scrape patterns at the CDN layer.
Bottom Line
for most iCIMS tenants, the XHR search API plus schema.org ld+json extraction gets you clean, structured job data without a headless browser. residential proxies are only necessary for the ~40% of tenants running Cloudflare. scale across hundreds of tenants with a discovery pipeline built on crt.sh and careful per-IP throttling. this site covers these ATS and structured-data scraping targets in depth -- bookmark it if you're building any kind of labor market or recruiting intelligence feed.
Related guides on dataresearchtools.com
How to Scrape Ashby Career Sites for Talent Pipelines (2026)
Ashby has quietly become the ATS of choice for fast-growing startups and Series B+ companies, which makes scraping Ashby career sites a high-signal move for talent pipeline builders, recruiting agencies, and competitive intelligence teams. The problem is that Ashby’s job boards aren’t served from a single domain — each company self-hosts under a pattern like
jobs.ashbyhq.com/— and the rendering is React-based, which trips up naive scrapers.How Ashby Job Pages Are Structured
Every Ashby career site follows a predictable URL schema:
https://jobs.ashbyhq.com/{company-slug} https://jobs.ashbyhq.com/{company-slug}/{job-id}The listing page renders a JSON payload into the DOM, but Ashby also exposes a public API endpoint that returns structured job data without JavaScript rendering:
GET https://api.ashbyhq.com/posting-api/job-board/{company-slug}This is the cleanest extraction path. The response is JSON with fields like
title,team,location,isRemote,employmentType, andapplicationFormDefinition. No authentication required, no browser needed.import httpx, json SLUG = "linear" # replace with target company slug resp = httpx.get(f"https://api.ashbyhq.com/posting-api/job-board/{SLUG}", timeout=15) data = resp.json() for job in data.get("jobs", []): print(job["title"], "|", job.get("location", {}).get("name"), "|", job["id"])Run this against a list of target slugs and you have a structured talent pipeline feed in minutes.
Finding Company Slugs at Scale
The slug discovery problem is where most pipelines break. There’s no public directory of all Ashby customers, so you need to build your own list.
Three approaches that work in 2026:
- Google dork:
site:jobs.ashbyhq.comreturns thousands of indexed subpaths. Paginate through results and extract the slug from the URL path. - LinkedIn scrape: Filter companies by ATS tech stack using tools like Clay or Phantom Buster, which surface ATS provider from careers page redirects.
- Common Crawl: Query the March 2026 crawl for
jobs.ashbyhq.comhostnames and extract unique slugs from theurlcolumn in Athena or BigQuery.
For a talent agency scraping 500+ companies, a seeded Common Crawl query gives the highest coverage per compute dollar.
Anti-Bot Behaviour and Rate Limits
The posting API (
api.ashbyhq.com/posting-api) is intentionally public and low-friction. Ashby wants jobs indexed. That said, hammering it with concurrent requests will get your IP soft-blocked within minutes.Realistic limits from testing:
Behaviour Observed limit Concurrent requests (same IP) ~5 before 429s appear Requests per minute (single IP) ~60 sustained Cooldown after 429 30-90 seconds User-agent rejection Not enforced on API Bot detection on HTML pages Cloudflare Turnstile (varies by company) The HTML job listing pages (
jobs.ashbyhq.com) are a different story. Some companies enable Cloudflare Turnstile on the front-end, which means rendering them requires a headless browser or a Turnstile solver. For bulk data extraction, stick to the API — avoid the HTML path entirely unless you need application form fields that aren’t exposed in the JSON.Rotate IPs per company slug, not per request. A residential proxy pool with 1 request per slug per session keeps your fingerprint clean and stays well within Ashby’s tolerance. If you’re also scraping other ATS platforms in the same pipeline — say, Recruitee or Personio — use separate proxy sessions per provider to avoid cross-contamination of block signals.
Normalising Ashby Data for Cross-ATS Pipelines
Raw Ashby output doesn’t map cleanly to other ATS schemas. If you’re building a unified talent intelligence feed that also pulls from iCIMS or Taleo, normalisation is the unglamorous work that determines whether your pipeline is actually useful.
Ashby-specific fields to watch:
location.namecan be"Remote", a city, or a hybrid string like"New York, NY (Hybrid)"— parse these consistentlyemploymentTypeuses Ashby’s own enum:"FullTime","PartTime","Contract","Temporary"— remap to your schemateamis a nested object withidandname, not a flat stringcompensationTierappears only when the company has salary transparency enabled — treat it as optional
A canonical schema across ATS providers should use ISO 3166-1 alpha-2 for country codes, a
remote_typeenum (full,hybrid,none), and Unix timestamps forposted_at. Ashby’screatedAtfield is UTC ISO 8601, which is straightforward to convert.The same normalisation discipline applies when you’re pulling structured data from completely different verticals — the schema design lessons in How to Scrape Latin American Real Estate Sites cover multi-source field unification patterns that transfer directly to multi-ATS pipelines.
Running This at Scale
For a production pipeline covering 1,000+ Ashby companies, the architecture is straightforward:
- Orchestration: Temporal or a simple cron on a VPS — Ashby jobs don’t change by the minute, so daily or twice-daily refreshes are enough
- Queue: Redis or SQS with one task per company slug
- Workers: 10-20 concurrent workers, each with a dedicated residential IP session
- Storage: Postgres with a
ats_jobstable and a(company_slug, job_id, scraped_at)composite key for deduplication - Change detection: Hash the job list per slug on each run and only emit events when the hash changes
Short bullet checklist before going to production:
- Confirm the slug list covers your target company set (test 10 manually)
- Set
httpxtimeout to 15s and retry twice with exponential backoff on 5xx - Log 429s with the slug and timestamp — patterns reveal which companies have extra rate protection
- Store raw JSON alongside normalised rows — Ashby’s schema has changed twice in the past 18 months
For monitoring, track the ratio of slugs returning zero jobs vs. a non-empty list. A sudden spike in zero-job responses usually means your IP pool is blocked, not that all your targets froze hiring simultaneously.
Bottom Line
The Ashby posting API is genuinely scraper-friendly — use it instead of rendering HTML, rotate IPs at the slug level, and invest the saved complexity into normalisation and deduplication. If you’re building a serious multi-ATS talent pipeline, Ashby is one of the easier integrations; the harder work is schema consistency across providers. DRT covers ATS scraping patterns, proxy infrastructure, and data pipeline design in depth — the same principles apply whether you’re pulling from five job boards or five hundred.
Related guides on dataresearchtools.com