Marks & Spencer Scraper - Products, Prices, Stock & Reviews
Pricing
from $1.50 / 1,000 product or review records
Marks & Spencer Scraper - Products, Prices, Stock & Reviews
Collect marksandspencer.com (M&S) products and individual reviews from keyword searches, categories or product links. Get prices, all colour galleries, size-level inventory, composition, care, ratings, and review responses, with filters, sorting, resume and recurring updates.
Pricing
from $1.50 / 1,000 product or review records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
1
Monthly active users
13 days ago
Last modified
Categories
Features
Share
Marks & Spencer Products and Reviews Scraper
Collect public product and review data from Marks & Spencer (marksandspencer.com). Search by keywords, browse a category, or paste product and search links. Save product prices, colour galleries, size-level inventory, composition and care information. Choose individual reviews when you need review text, ratings, recommendations and retailer responses.
Why This Scraper?
- Three ways in. Search terms, category browsing and multiple pasted links.
- Filters. Department, brand, colour, size, price and additional store filters.
- Sorting. Six product sorts and four review sorts.
- Rich detail. Full descriptions and galleries across available colour variants.
- Size-level stock. Individual size SKUs with the inventory and prices published by the store.
- Recurring runs. Resume an earlier collection or collect recurring changes.
- Export. Export saved results to your connected apps.
Use Cases
- Fashion resellers and price trackers: watch a product, a search or a whole category for price and stock changes before restocking.
- Affiliate and comparison sites: pull complete descriptions, colour galleries and prices to publish accurate listings without manual entry.
- Review and reputation analysis: collect review text, ratings, recommendation flags and retailer responses to track recurring praise or complaints on a range.
- Merchandising and competitor research: browse a department or category by best selling, new arrivals or rating to see what is being pushed.
- Size and stock monitoring: track individual size SKUs and published inventory for a product to catch restocks or sellouts.
- Recurring collection pipelines: schedule the same search, category or links and receive only the products and reviews that changed since the last run.
Data You Get
Sample shape: values are illustrative placeholders, not from a live product.
| Field | Example |
|---|---|
recordType | product or review |
id | P00000001 |
title | Sample cashmere jumper |
brand | Sample Brand |
price | 50 |
previousPrice | 60 when published |
currency | GBP |
unitPrice | Price per published quantity and unit |
averageRating | 4.5 |
reviewCount | 10 |
images | Gallery links from available colours |
variants | Colour variants, images, size SKUs and inventory |
colours | ["Navy", "Black"] |
sizes | ["Small", "Medium"] |
composition | Sample fabric composition |
careInstructions | ["Sample care instruction"] |
attributes | Complete published product attributes |
promotions | Published offer text and terms |
reviewText | Sample review text |
secondaryRatings | Published fit, quality and value scores |
clientResponses | Published retailer review responses |
productId | Product identifier shared by product and review rows |
changeType | NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED |
Fields vary by product category and output type. Missing source values remain empty or null. Product details add the complete published attributes and colour/size structures. A separate sub-brand is not inferred from the main brand. Review rows retain the public reviewer nickname and published syndication and verification information.
How to Use
Search for products
The default search is cashmere jumper. Max items counts saved rows across the whole run.
Search by keyword:
{"mode": "search","searchTerms": ["cashmere jumper"],"maxItems": 20}
Apply product filters
Use exact store filter values. Additional filters accept one Property=value pair per entry.
Filter products:
{"mode": "search","searchTerms": ["cashmere jumper"],"department": "Womens","brands": ["Autograph"],"minPrice": 50,"maxPrice": 100,"sortBy": "price_low","maxItems": 20}
Browse a category
A filled category replaces search terms. Product filters and sorting still apply.
Browse a category:
{"mode": "search","category": "/l/women/knitwear","sortBy": "new","fetchDetails": true,"maxItems": 20}
Collect individual reviews from links
URL mode uses only pasted links for discovery. Search-mode fields are ignored. Supported link shapes (www.marksandspencer.com or marksandspencer.com):
- Product:
/<name>/p/clp<digits>(alsohbp,ftp,flpids), optionally with a colour query. - Keyword search:
/search?q=..., withpageandsort(for example PRICE_LOW_TO_HIGH). - Category:
/l/women/knitwear, withpage,departmentandsortparameters. - Nested sub-category:
/l/women/knitwear/jumpers. - Brand collection:
/l/brands/jaeger/womens.
Left untouched, url mode run with the field untouched now scrapes one example of each shape (the default and the prefill are the same twelve links, no longer a single product). The cost of an untouched run is bounded by Max items (default 20 products in total across all links, each saved row billed as usual, plus detail enrichment when product details are on); lower Max items or replace the links to spend less. Products (with or without a colour query), category and nested sub-category links, brand collections, keyword search links (paginated, sorted or department-filtered) and links without www can share the same URL list. Unsupported links stop the run with a clear message. A search or category link preserves its filters, ordering and starting page.
Collect reviews from links:
{"mode": "url","urls": ["https://www.marksandspencer.com/pure-cashmere-crew-neck-jumper/p/clp61223565"],"outputType": "reviews","reviewSort": "recent","reviewRatings": ["4", "5"],"maxReviews": 20}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/marksandspencer-scraper").call(run_input={"mode": "search", "searchTerms": ["cashmere jumper"], "maxItems": 20})for product in client.dataset(run["defaultDatasetId"]).iterate_items():print(product["title"], product["price"], product["currency"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/marksandspencer-scraper').call({ mode: 'search', searchTerms: ['cashmere jumper'], maxItems: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Limits and charges
Every saved product or individual review is one result item. Products and reviews use separate budgets: Max items caps product rows, Max reviews caps review rows. With Products and reviews selected, both record types are saved and billed independently. Reviews output saves review rows without a separate product row. maxReviewsPerProduct limits reviews for each product (default 20, maximum 10000); 0 has no separate limit. maxPages is optional; blank or 0 walks until the source ends or Max items (product pages) or Max reviews (review pages) is reached.
Both extra events are recorded as each row is saved, so a run that stops early is billed only for rows already delivered. Enriched product rows add one detail-enrichment event per successfully saved product. Individual reviews add one review-scraped event per saved review row, in addition to the saved-item event. Skipped products, failed enrichment and suppressed recurring rows do not add a detail charge. Expired rows are result items but do not add a detail charge. An expired review row still adds the review-scraped event, like any other saved review row. See the actor pricing panel for the active prices.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | Choose keyword search or pasted links. Only the inputs in the selected mode are used. |
searchTerms | array | ["cashmere jumper"] | Search each term separately. Defaults to cashmere jumper. Ignored when category is filled or mode is url. |
department | string | Optional | Optional clothing department: Womens or Mens. Applies the store department filter in search mode only. |
category | string | Optional | Optional category path, category link or SubCategory identifier. Browse this category instead of search terms. Search filters and sort still apply. |
brands | array | Optional | Optional exact brand names shown in the store filters, such as Autograph or JAEGER. Search mode only. |
colours | array | Optional | Optional colour filter names, such as Navy or Black. Search mode only. |
sizes | array | Optional | Optional exact size filter labels, such as S, M or 10. Search mode only. |
facet | array | Optional | Optional native filter pairs, one per line, such as Fit=Regular fit or Neck Type=Crew neck. Use the exact filter name and value shown for your search. Search mode only. |
minPrice | integer | Optional | Optional minimum price in GBP. Search mode only. |
maxPrice | integer | Optional | Optional maximum price in GBP. Search mode only. |
minRating | integer | Optional | Optional minimum average product rating from 0 to 5. Search mode only. |
sortBy | string | relevance | Use the store ordering in search mode. URL mode preserves the ordering specified in each link. |
urls | array | twelve example links, one per supported shape | Paste one or more M&S product, category or search links. Left untouched, url mode scrapes one example of each supported shape, bounded by Max items. Search-mode fields are ignored. Results begin at the page specified in each link. |
outputType | string | products | Products saves product rows. Reviews saves individual review rows. Products and reviews saves both, joined by productId. Saved products count toward Max items; saved reviews count toward Max reviews, a separate budget. |
fetchDetails | boolean | true | Add full descriptions, composition, care, all colour galleries and size-level inventory. Each successfully saved enriched product adds one detail-enrichment charge. Reviews are separate saved items. Suppressed, skipped and failed rows do not add this charge. |
reviewSort | string | recent | Ordering for individual review rows in Reviews or Products and reviews output: most recent, oldest, highest rated, lowest rated, most helpful or least helpful. |
reviewRatings | array | Optional | Optional exact star ratings to include, from 1 to 5. Empty includes all ratings. Applies to review output only. |
maxReviewsPerProduct | integer | 20 | Limit on individual review rows per product. Set 0 to collect all available reviews for each product until Max reviews is reached (maximum 10000). |
maxPages | integer | Optional | Optional limit on result or review pages per source. Blank or 0 means unlimited pages until the source ends or the relevant budget is reached: Max items for product pages, Max reviews for review pages. No default page cap. |
maxItems | integer | 20 | Maximum saved product rows across the run, including recurring update rows. Default 20. Set 0 for unlimited products. Reviews use the separate Max reviews budget and never count against this. |
maxReviews | integer | 20 | Maximum saved review rows across the run, independent of Max items. Default 20. Set 0 for unlimited reviews (still bounded by Maximum reviews per product and Maximum pages per source, if set). Values above 1000000 are not accepted. |
resumeFromRunId | string | Optional | Optional previous run or dataset ID. Skip previously saved product and review IDs. Combine datasets to continue a collection. Resumed runs do not emit expired rows. For recurring collection, use incrementalMode instead. |
incrementalMode | boolean | false | Remember this exact collection scope between runs. Return NEW, UPDATED or REAPPEARED rows. Use stateKey to name the collection, emitUnchanged to include unchanged rows and emitExpired for missing rows. |
stateKey | string | Optional | Optional name for a recurring collection. The selected mode, output type, terms or links, filters and detail setting also identify its baseline; review sort, rating and per-product limits do not. Different scopes never share a baseline. |
emitUnchanged | boolean | false | Incremental mode only. Also save unchanged products or reviews marked UNCHANGED. Each saved row is charged as an item; saved enriched products can add the detail charge. |
emitExpired | boolean | false | Incremental mode only. Save EXPIRED rows after a complete collection. No expiration after a cap, resumed run or incomplete source. Expired rows count as saved items and do not add a detail charge. |
ignoreFieldsForChanges | array | [] | Incremental mode only. Field names (dotted paths such as variants.price are allowed) that never mark a row UPDATED and never appear in changedFields. Ignored fields stay in the output. Volatile fields scrapedAt, searchTotal, searchTerm, searchIndex, input, matchedFilters and lastSeenAt are always ignored. |
proxy | object | Apify proxy | Standard Apify connection configuration. |
mcpConnectors | array | Optional | Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a page per record; other connectors get a best-effort write or digest. Each connector receives a condensed summary per record, not the full record; the complete record always stays in the dataset. Leave empty to skip; this never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com). |
notionParentPageUrl | string | Optional | URL or id of the Notion page under which record pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListings | integer | 50 | Maximum saved items to send to each selected connector. Does not limit or change the dataset. |
Resume and recurring collections
Use resumeFromRunId to skip IDs already saved in an earlier run or dataset. This is useful for collecting the next part of a large result set with another run. The new dataset contains only the rows collected by that run.
Use incrementalMode for recurring collection of the same scope. The first run saves NEW rows; later runs save UPDATED or REAPPEARED rows when relevant. With emitUnchanged enabled, unchanged rows are also saved and billed as items. Use stateKey to name your collection. Different filters or output settings keep separate baselines. With Products and reviews output, a product already covered by resumeFromRunId is skipped, but its reviews are still collected, since reviews use their own separate budget.
Missing rows are emitted only with emitExpired after a complete collection. A capped, resumed or incomplete run cannot establish that an unseen product or review disappeared. A source changing its published price, inventory, review text or other collected data can produce an update. Collection timestamps do not themselves produce an update. Expired rows share the maxItems or maxReviews budget with new and updated rows. If more of your tracked collection disappears at once than that budget allows to report in one run, the extra missing rows stay untouched in your saved baseline and are reported as EXPIRED by a later run. For example, if 7 tracked products disappear and maxItems is 3, that run reports 3 EXPIRED rows and the next complete run reports more. Set maxItems or maxReviews to 0, or comfortably above the size of your tracked collection, whenever emitExpired matters to you.
Send results into your apps (MCP connectors)
Select optional mcpConnectors to send copies of saved results to your connected apps. Authorize connectors in Apify Settings, API & Integrations, before selecting them. Notion, Linear, Airtable and Apify connectors are supported. For Notion, supply notionParentPageUrl for the destination page. maxNotifyListings limits how many saved rows are sent to each connector. This export does not alter or limit your dataset. A connector error leaves the saved scrape results available. Leave the connector list empty to skip export.
Output Example
Sample shape: values are illustrative placeholders, not from a live product.
{"recordType": "product","id": "P00000001","productId": "P00000001","title": "Sample cashmere jumper","brand": "Sample Brand","url": "https://www.marksandspencer.com/sample-product/p/clp00000001","productUrl": "https://www.marksandspencer.com/sample-product/p/clp00000001","description": "Sample full product description.","price": 50,"previousPrice": 60,"currency": "GBP","averageRating": 4.5,"reviewCount": 10,"images": ["https://assets.digitalcontent.marksandspencer.app/image/upload/00000001"],"colours": ["Navy"],"sizes": ["Small"],"composition": "Sample fabric composition","careInstructions": ["Sample care instruction"],"variants": [{"id": "00000001","skus": [{"id": "00000001001","size": {"primarySize": "Small"},"inventory": {"quantity": 10, "quantityOnHand": 10, "quantityAdvised": 0}}]}],"attributes": {"sampleAttribute": "Sample value"},"fetchedDetails": true,"changeType": "NEW","changedFields": [],"firstSeenAt": "2026-01-01T00:00:00.000Z","lastSeenAt": "2026-01-01T00:00:00.000Z"}
Individual review rows have recordType: "review", a review ID, productId, productUrl, review text, rating, public nickname, submission time and the other published review fields. The default Results view includes headline fields for both record types. Products and Reviews views offer dedicated columns. All fields remain available in dataset JSON.
Plan Requirement
An Apify account is required. Consult the actor pricing panel before starting a run. The default connection setting uses Apify's standard proxy pool. Whether a datacenter-only connection is enough for marksandspencer.com has not been confirmed: pages loaded in direct tests, but no test went through an Apify datacenter proxy. If the standard connection is refused, the actor continues on a backup connection and notes it in the run status message ("Served over the backup connection"). If the proxy connection is refused for the account, the run stops with a message that a paid Apify plan is required or that your own proxy URLs need valid credentials. Apify free plans do not include residential proxies. Selecting the residential connection group applies a small internal request and data limit for that run, so it suits short runs only. A run that reaches this limit stops gracefully, keeps the rows already saved and reports itself as incomplete in its status message.
FAQ
How much does it cost?
You pay per saved product or review row, plus one extra event when a product finishes detail enrichment and one extra event per saved review row. The Pricing tab shows the current rates. Use Max items and Max reviews to cap the cost of any run.
Is it legal to scrape Marks & Spencer?
This actor collects only publicly available product and review data from marksandspencer.com. You are responsible for how you use it: follow the site's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product prices and descriptions are generally facts, but review text, photos and brand names may carry separate rights.
Can I get only new or changed products on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Recurring updates. Each run then returns only NEW, UPDATED or REAPPEARED rows for the same search, category or links, and unchanged rows are not billed unless Include unchanged rows is also on.
Why do some product rows have fewer fields than others?
Include product details controls this. On, every product adds full descriptions, composition, care instructions and colour and size galleries. Off, search and category results still keep the fields shown on the results page, such as price, rating and any listed colours or sizes, while a pasted product link keeps only a smaller core field set (identifiers, links, title, brand, price, currency, rating, review count and images). Turn Include product details on for the complete published data on every product.
Why didn't Include missing rows report everything that disappeared?
Include missing rows shares the Max items or Max reviews budget with new and updated
rows. If your tracked collection loses more items in one run than that budget allows to report, the extra missing rows are still recorded internally as gone and will not be offered as expired again later either, unless they reappear in the source. For example, 7 disappeared products with Max items set to 3 give 3 EXPIRED rows, and the other 4 are never reported. Set Max items or Max reviews to 0, or comfortably above the size of your tracked collection, whenever you rely on this option.
Why did my run fail instead of returning an empty dataset?
If a pasted link or a category path cannot be read, the run fails with a message instead of quietly returning nothing. Check that every link is a valid Marks & Spencer product, category or search link, then run it again in a few minutes. If result pages cannot be read once the search has started, the run keeps any rows it already saved and its status message ends with "Collection stopped before every result was scanned." A search that genuinely has no matching products returns an empty dataset without that note.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push saved results into Notion, Linear or Airtable.
๐ More scrapers you might like
Pair this actor with these related scrapers from the same team:
| ๐ UNIQLO Scraper Scrape UNIQLO products across 21 country storefronts in local currency. Price with pre... | ๐ Next.co.uk Scraper Scrape Next.co.uk: keyword search, category and product-listing walks, full product... |
| ๐ 24S Scraper Scrape 24S luxury fashion by category, filters, or URL. Extract brand, name, price... | ๐ Kmart Scraper Scrape products and customer reviews from Kmart.com.au. Search by keyword or use... |
| ๐ Fashion Nova Scraper Scrape Fashion Nova products by keyword, collection or URL. Extract product names... | ๐งฉ ASOS Scraper Scrape ASOS by keyword, category or URL. Every row carries the selling price and the... |
๐ Browse all abotapi scrapers
๐ฌ Support
- ๐ Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- ๐ ๏ธ Need another site, extra fields or a private build? Email contact@abotapi.com.
- โญ Enjoying it? A quick review on the actor page helps other users find it.