Tony Wang6 min readHow to Scrape Old Navy in 2026 (API & Python)
Scrape Old Navy, Gap, Banana Republic, and Athleta in 2026 — search, category browsing, pricing, and store locations as JSON — DIY, no-code, or API.
The fastest way to scrape Old Navy in 2026 is to call a structured API that returns normalized JSON for product search, category browsing, product detail, and store locations — instead of parsing Old Navy's pages yourself. The bigger unlock is that the same API also covers the rest of the Gap Inc. storefront family: Gap, Banana Republic, and Athleta all share the same endpoints, switched with one brand parameter. This guide covers all three approaches, what each returns, where DIY breaks, and the legal and access basics.
Why scrape Old Navy?
- Multi-brand retail intelligence in one pipeline — Old Navy, Gap, Banana Republic, and Athleta all sell through the same Gap Inc. corporate parent, and this API mirrors that with one schema across all four brands, so a single search or product-detail call covers the whole portfolio.
- Cross-brand price comparison — the same silhouette (a basic tee, a pair of joggers) often shows up across Old Navy, Gap, and Athleta at different price points; comparing them means querying each brand with the same keyword.
- Pricing and markdown tracking — Old Navy runs frequent promotions; re-running search or product detail on a schedule tracks price and discount movement per color and size.
- Assortment and category research — see what a category carries and how counts shift, per brand.
- Store coverage mapping — find nearby physical stores for a brand by zip code, city, or coordinates, useful for local-availability or store-density research.
Is it legal to scrape Old Navy?
Option 1: DIY in Python (and why it breaks)
A naive approach fetches a product page and parses the rendered HTML:
import requests
from bs4 import BeautifulSoup
resp = requests.get(
"https://oldnavy.gap.com/browse/product.do?pid=123456002",
headers={"User-Agent": "Mozilla/5.0 (compatible; research-bot/1.0)"},
)
soup = BeautifulSoup(resp.text, "html.parser")
# Price, color, and size availability are embedded in page data,
# not consistently exposed as stable, selectable markup
It demos and then breaks:
- Four separate brand domains, one underlying platform. Old Navy, Gap, Banana Republic, and Athleta each run their own storefront domain under the shared Gap Inc. corporate umbrella — a scraper built against
oldnavy.gap.comdoesn't transfer cleanly togap.com,bananarepublic.gap.com, orathleta.gap.comwithout rework. - Anti-bot defenses front the sites. Routine, unauthenticated requests get challenged or blocked quickly, and a browser-based scraper needs ongoing upkeep as the defense updates.
- Color and size fragment a single "product." A search hit isn't the full product — each color variant carries its own product id, and each size within a color carries its own price and availability, so a single page fetch never gives you the full picture.
- Category navigation isn't a static list. There's no published list of category ids to iterate — you have to resolve them from the live site first, and for Gap, Banana Republic, and Athleta that navigation renders as client-side-only JavaScript, so a plain HTML fetch won't even show it.
Option 2: No-code tools
Point-and-click scrapers and browser extensions can export a single search results page for one brand, but tracking price and assortment across four related brands on a schedule is a recurring pipeline job — better served by an API you can call from a script or cron job than a manual export tool.
Option 3: A structured Old Navy API
Crawlora's Old Navy API returns normalized JSON for search, category browsing, product detail, and store locations — across Old Navy, Gap, Banana Republic, and Athleta, selected with one brand parameter (on, gap, br, or at, defaulting to on). Search by keyword:
curl "https://api.crawlora.net/api/v1/oldnavy/search?query=joggers&brand=on" \
-H "x-api-key: $CRAWLORA_API_KEY"
Switch brands with the same call by changing brand:
curl "https://api.crawlora.net/api/v1/oldnavy/search?query=joggers&brand=gap" \
-H "x-api-key: $CRAWLORA_API_KEY"
Then resolve a color-specific product id from a search result and pull full detail in Python:
import requests
h = {"x-api-key": "YOUR_API_KEY"}
base = "https://api.crawlora.net/api/v1/oldnavy"
hits = requests.get(f"{base}/search", headers=h, params={"query": "joggers", "brand": "on"}).json()["data"]["products"]
first_color = hits[0]["colors"][0]
pid = first_color["pid"]
detail = requests.get(f"{base}/product", headers=h, params={"pid": pid, "brand": "on"}).json()["data"]
Category browsing needs a category id — resolve current ids first (Old Navy only for now), then pull that category's listing and live facets:
categories = requests.get(f"{base}/categories", headers=h).json()["data"]["categories"]
cid = categories[0]["cid"]
listing = requests.get(f"{base}/category", headers=h, params={"cid": cid, "brand": "on"}).json()["data"]
Store locations take a zip code, city, or coordinates, per brand:
curl "https://api.crawlora.net/api/v1/oldnavy/stores?zip=94103&brand=on" \
-H "x-api-key: $CRAWLORA_API_KEY"
Check exact field names in the docs before wiring a pipeline. Store one row per product per color per pull, keyed by pid, and re-run search or product detail on a schedule to track price and availability changes.
What you can collect
Public product and store data, across all four Gap Inc. brands by passing brand: search results (product summaries with pricing and every color variant); full product detail per color-specific pid, including per-size pricing; category listings with live search facets, once a cid is resolved (/oldnavy/categories currently resolves ids for Old Navy only, since Gap, Banana Republic, and Athleta render navigation as client-side-only JavaScript); and nearby physical stores by zip code, city, or coordinates, including address, phone, and distance. Public storefront data only — not account, order, or payment information, and store lookups don't report per-item stock levels.
Limitations and common challenges
- Anti-bot defenses on the front end. Expect challenges on naive or high-volume automated requests against the storefronts directly.
- Category ids for three of the four brands aren't resolvable yet.
/oldnavy/categoriesonly covers Old Navy today — Gap, Banana Republic, and Athleta navigation renders as client-side-only JavaScript, so there's no equivalent id list for those brands yet. - Product ids are color-specific. A search hit isn't a single product id — pull the
pidfrom a result'scolors[]array before requesting detail, or you'll get the wrong variant. - No per-item stock in store lookups.
/oldnavy/storesreturns nearby physical stores and contact details, not whether a specific item is in stock at that location. - Public data only. This is what a product, category, and store-locator page already show publicly — not a way around a login or into account-level data.
Where this gets used
- Cross-brand pricing intelligence — track how the same style (a basic tee, joggers, a puffer jacket) is priced across Old Navy, Gap, Banana Republic, and Athleta.
- Assortment research — measure category counts and coverage by keyword, per brand.
- Local availability and store-density mapping — pair store lookups by zip code with product search to model regional coverage.
Sources
Start collecting
Try it first, free: run any public URL through the Free Web Scraper, or check whether a site blocks bots with the Anti-Bot Checker — no signup.
Test the search, product, category, and store endpoints in the Playground, check the schema in the API docs, and review pricing. For the same search-to-detail shape on a fashion marketplace with per-country storefronts, see how to scrape Zalando; for a single-brand athletic-wear comparison, see how to scrape Nike; and for another fast-fashion chain, see how to scrape Zara. See also how to choose a web scraping API and is web scraping legal.
Part of our how-to-scrape guide series — every platform we cover, in one index.
Frequently asked questions
Does the Old Navy API also cover Gap, Banana Republic, and Athleta?
Yes — /oldnavy/search, /oldnavy/category, /oldnavy/product, and /oldnavy/stores all take a brand parameter (on, gap, br, or at, defaulting to on) to select the storefront. /oldnavy/categories currently only resolves ids for Old Navy, since the other three brands render their navigation as client-side-only JavaScript.
How do I browse Old Navy categories with an API?
Old Navy's storefront navigation isn't published as a static id list — call /oldnavy/categories to resolve the current category ids as name/cid pairs, then pass a cid to /oldnavy/category for that category's product listing.
Can I find nearby Old Navy store locations?
Yes — /oldnavy/stores returns nearby physical stores by zip code, city, or coordinates, including address, phone, and distance. It does not report per-item stock levels.