myntra-scraper
A Python scraper for Myntra, India's largest fashion marketplace. Two jobs:
- Listings and search: any listing or search URL (
/men-tshirts,/levis?rawQuery=levis, with sort and filters) → name, brand, price, MRP, discount, rating, rating count, sizes, colour, image and URL. Real pagination, 50 products per page, sponsored products left out. - Product pages: price, MRP, rating and attributes, plus one row per size and seller with that seller's price and the exact units in stock.
Output as Python dicts, JSON or CSV. One dependency (requests), no browser.
pip install myntra-scraper
Why a plain request fails
Myntra sits behind Akamai Bot Manager (_abck, bm_sz cookies). A script doesn't get an error, it gets nothing:
| Request | Result |
|---|---|
requests, default or Chrome user agent |
connection opens, no bytes, timeout after 20 s |
curl (HTTP/2) |
stream was not closed cleanly: INTERNAL_ERROR |
| Through Scrape.do, no parameters | 200 in ~3 s, full page, 1 credit |
Pages are fetched through the Scrape.do API with a plain request: no render, no super, 1 credit per page. You need a Scrape.do API token; the free plan includes 1,000 credits a month.
Quick start
from myntra_scraper import MyntraScraper
scraper = MyntraScraper(token="YOUR_SCRAPEDO_TOKEN") # or set SCRAPEDO_TOKEN
# 3 pages of 50 = 150 products (4 credits: one page visit + three API pages)
rows = scraper.get_listing("https://www.myntra.com/men-tshirts?sort=new", max_pages=3)
for row in rows[:3]:
print(row["brand"], row["name"], row["price_inr"], row["mrp_inr"], row["discount_pct"])
product = scraper.get_product(rows[0]["url"])
print(product["units_in_stock"], product["sizes_in_stock"], "/", product["sizes_total"], "sizes in stock")
for size in product["sizes"]:
print(size["size"], size["seller"], size["price_inr"], size["units"])
Command line
export SCRAPEDO_TOKEN=your_token
# 3 pages of a listing, CSV
myntra-scraper listing "https://www.myntra.com/men-tshirts?sort=new" --pages 3 -f csv -o myntra-listing.csv
# product summaries for the first 10 products from that file
myntra-scraper product -i myntra-listing.csv --limit 10 -f csv -o myntra-products.csv
# one row per size and seller
myntra-scraper product -i myntra-listing.csv --limit 10 --sizes -f csv -o myntra-sizes.csv
product reads the url column of the listing CSV, so the commands chain.
Output
Size rows (from the fictional test page in tests/fixtures):
[
{"product_id": 90000001, "size": "M", "sku_id": 900000012, "available": true,
"seller": "Example Retail Two", "seller_id": 202, "price_inr": 449, "mrp_inr": 999, "units": 5},
{"product_id": 90000001, "size": "M", "sku_id": 900000012, "available": true,
"seller": "Example Retail One", "seller_id": 101, "price_inr": 469, "mrp_inr": 999, "units": 30}
]
Listing columns: product_id, name, brand, price_inr, mrp_inr, discount_pct, rating, rating_count, sizes, gender, article_type, colour, image, url.
Product columns: product_id, name, brand, price_inr, mrp_inr, discount_pct, rating, rating_count, colour, article_type, gender, country_of_origin, sizes_in_stock, sizes_total, units_in_stock, lowest_size_price_inr, highest_size_price_inr, sellers, url (plus attributes and sizes in Python/JSON).
How it works
The data is one JSON object. Myntra renders every page on the server and puts the data in an inline script, window.__myx = {...}. Listings keep their products in searchData.results.products, product pages keep everything in pdpData. The scraper finds the assignment and reads the object with json.JSONDecoder.raw_decode. No CSS selectors.
Sponsored products are separate. A listing page carries the organic results in products and the ads in plaProducts (18 of them on a men's T-shirts page). Only the organic products are returned.
?p=2 is ignored. Ask the HTML for page 2, 3 or 50 and you get the first 50 products again. In our test, page 2 of a listing sorted by newest shared 49 of 50 products with page 1. The site pages through its search API, /gateway/v4/search/<slug>, which:
- returns 401 without the cookies a page visit sets (
at,_abck,bm_szand others), and - ignores
pandoas well, unless the request carries apagination-contextheader. Every API response returns a newpagination-contextheader; sending it back moves to the next 50.
Not every visit hands out a usable session: in our tests roughly one visit in four came back with a single cookie, and the API answered 401 to it. The scraper repeats the visit until Myntra's at cookie is there, and gets fresh cookies if the API still says 401.
So get_listing(max_pages=N) visits the listing once for its cookies, then calls the search API N times, passing the cursor from each response to the next request (Scrape.do forwards the cookie and cursor headers with extraHeaders=true). In our test, four API pages returned 200 distinct products.
Listing price vs size price. A listing card has one price. On the product page every size lists its sellers, each with its own price and stock count. On a Levi's T-shirt listed at ₹389, sizes M and XL had a seller at ₹389 while sizes S and L were only available from a second seller at ₹402. The sizes rows keep that split.
Limits
- One location. Prices and stock are what Myntra shows without a delivery pincode.
- Credits.
max_pages=1reads the listing HTML (1 credit). More pages cost one page visit plus one credit per API page. - Errors. Non-200 responses raise
ScrapeErrorwith the status code;from_targettells a Myntra status from a Scrape.do one (a wrong token is a Scrape.do 401). A 200 without Myntra's data (an Akamai page) is treated as a failure. Server errors, 429s and empty pages are retried twice; client errors are not.
Responsible use
The scraper reads listing, product and search pages, which Myntra's robots.txt allows (Allow: /); it does not touch cart, checkout, account or size-chart paths. Product data is not personal data. Read Myntra's terms for your use case and keep request rates modest. This is not legal advice.
Development
git clone https://github.com/bugrahansss/myntra-scraper
cd myntra-scraper
pip install -e .
python -m unittest discover -s tests -v
The tests run offline against fictional fixture pages.
License
MIT
Built and tested with Scrape.do, November 2026.
Metadata
Release files for myntra-scraper 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| myntra_scraper-0.1.1.tar.gz | 19.0 kB | Without provenance | Details for myntra_scraper-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| myntra_scraper-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for myntra_scraper-0.1.1-py3-none-any.whl |
Total release size: 32.7 kB
Release files / myntra_scraper-0.1.1.tar.gz
| Download URL | myntra_scraper-0.1.1.tar.gz |
|---|---|
| Size | 19.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
15d8a98797bfd519f0c15ca06460fde9bbd4cedc4e254e84e41b7961cb3b2d9c
|
|
BLAKE2b-256 checksum How to use checksums |
7c8e2408d490e64361803a6fc4689b61914dc6b3e30f10e08d2cd9d648105c3f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / myntra_scraper-0.1.1-py3-none-any.whl
| Download URL | myntra_scraper-0.1.1-py3-none-any.whl |
|---|---|
| Size | 13.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1b674c56048c0b4f0da05de2c11e433dd5f415fd57bd0dbf11203d50cc31ca8a
|
|
BLAKE2b-256 checksum How to use checksums |
c32c345c1c5dd6b089c55ab05c1f53f33f1d5fa1aac6530625200d1b302df5c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Security for myntra-scraper 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.