Skroutz Scraper - Greek Price Comparison & Product Prices
Pricing
from $0.50 / 1,000 run start fees
Skroutz Scraper - Greek Price Comparison & Product Prices
Search Skroutz or paste a category URL and get one row per Greek product: title, the lowest price across every shop Skroutz compares, currency, rating, review count, image and a stable SKU id. Up to 600 products per run. For price monitoring, assortment research and Greek market analysis.
Pricing
from $0.50 / 1,000 run start fees
Rating
0.0
(0)
Developer
SR
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
0
Monthly active users
18 days ago
Last modified
Categories
Share
Skroutz Scraper
The Skroutz scraper turns skroutz.gr, Greece's dominant price-comparison site, into clean rows: the lowest price across every shop Skroutz compares, plus rating, review count and a stable SKU id. Pass a search term or a category URL and take one row per product, up to 600 per run.
Skroutz is not a single retailer. Each listing is a product that many Greek shops offer, and price_from is the market floor for that product. A category run is therefore a direct answer to "what is the cheapest anyone sells this for in Greece right now?" — without opening one shop tab per row.
What the Skroutz scraper returns
- A market minimum.
price_fromis the lowest offer Skroutz compares for that product - Rating and review count as numbers, from the site's own aggregate
- Stable SKU ids parsed from the product URL, so two runs join cleanly
- Honest pagination. A search returns one page of about 52 products and no pagination parameter moves it; the run says so instead of looping over the same 52 rows. Category URLs (
/c/<id>/…) page deeper - Success scored on the data. An interstitial page also answers 200, so the run only succeeds when the product list is actually present
- $0.0005 start fee + $0.003 per product. Empty results cost nothing beyond the start fee
A row looks like this (first product of a search for laptop, 2026-10-06):
{"position": 1,"sku_id": "61438939","title": "HP Victus 15-fb3093dx 15.6\" IPS FHD 144Hz (Ryzen 7-7445HS/16GB/512GB SSD/GeForce RTX 4050/W11 Home) (US Keyboard)","url": "https://www.skroutz.gr/s/61438939/hp-victus-15-fb3093dx-15-6-ips-fhd-144hz-ryzen-7-7445hs-16gb-512gb-ssd-geforce-rtx-4050-w11-home-us-keyboard.html","price_from": 1055.18,"currency": "EUR","rating": 4.84615,"reviews_count": 13,"image": "https://d.scdn.gr/images/sku_main_images/061438/61438939/xlarge_20251002161814_hp_victus_15_fb3093dx_15_6_ips_fhd_144hz_ryzen_7_7445hs_16gb_512gb_ssd_geforce_rtx_4050_w11_home_us_keyboard.jpeg","brand": null,"query": "laptop"}
Every row also carries the marketplace contract fields source ("skroutz-scraper"), country ("GR"), fetched_at (ISO 8601 UTC), product_id (same value as sku_id), price and lowest_price (same value as price_from) and image_url (same value as image), so a row can be joined with data from other markets without renaming columns.
Input
| Field | Type | Required | Default | What it does |
|---|---|---|---|---|
query | string | one of query/url | – | What to search for. Greek and English terms both work |
url | string | one of query/url | – | A category URL such as /c/40/laptop.html, or any absolute/partial URL resolved against skroutz.gr. When set it wins over query. Only /c/<id>/ URLs paginate |
sort | select | no | relevance | Relevance, popularity or newest. Any other value falls back to relevance. Sorting by price is deliberately not offered: that ordering returns a payload with the prices stripped out |
limit | integer | no | 52 | Products to return, 1 to 600. A page carries about 48–52. Whole numbers may arrive as a number or as text ("200"); 0 or an empty value falls back to 52 |
use_proxy | boolean | no | false | Off by default. Turn it on only if Skroutz starts refusing your runs |
retries | integer | no | 6 | Attempts per page, 2 to 12, with the same number-or-text leniency as limit (0 or empty falls back to 6). Each attempt climbs to the next request shape |
cursor | string | no | – | New. Send back next_cursor from the previous response with the same query/url and sort to continue a category |
Four inputs are enough for most runs:
{"query": "laptop"}— one search page, about 52 products{"url": "/c/40/laptop.html", "limit": 200}— a category, three pages, 200 unique products{"query": "laptop", "sort": "popularity"}— Skroutz's popularity ordering on a search{"url": "/c/40/laptop.html", "limit": 600, "sort": "newest"}— a whole category, then continue withnext_cursor
query and url may both be filled; url is what gets fetched, and query is still echoed on every row, which is how a mixed input stays traceable. There is no schema requirement forcing one of them: an empty run comes back successful and empty with a bad_input note, exactly like earlier versions of this actor.
Output
One row per unique product, deduplicated on sku_id (falling back to the product URL):
| Field | Type | Notes |
|---|---|---|
position | integer | 1..n after deduplication and the limit cut, across all pages |
sku_id | string | null | Taken from /s/<id>/ in the product URL; stable across runs |
title | string | Product name as Skroutz lists it, whitespace compacted |
url | string | null | Absolute product URL |
price_from | number | null | Lowest price across the compared shops. Whole prices come back as JSON integers (931), others as decimals (1055.18) |
currency | string | EUR |
rating | number | null | Out of 5, passed through as published — 5 or 4.84615 |
reviews_count | integer | null | Number of reviews behind the rating |
image | string | null | Main product image URL |
brand | string | null | Filled when Skroutz publishes one on the listing |
query | string | null | Echo of your search term; null when you passed only url |
When a category has more rows than limit, the run continues from a cursor and keeps positions and SKU ids unique across pages. When nothing is found, the run finishes successfully with zero rows and a clear reason — never as a crash.
Besides the rows, the run writes a summary (itemCount, errorCount, paginates, singlePageNote, pagesRequested, pagesServed, productsReturned, withPrice, withRating, fetchedInSeconds) and, when something went wrong, an errors list with a code and an English message. Codes you may see: bad_input, bad_url, no_results, challenged, fetch_failed. Only the first three are ordinary: they end the run successfully with zero rows. A blocked or timed-out page is retried within the attempt budget and reported if it never arrives.
The run summary and errors live in the key-value store, the products in the default dataset. Everything is readable through the Apify API, the console, or the MCP endpoint attached to this actor.
Use cases
Greek market pricing. A category run gives you the market floor per product without visiting a single retailer. Compare your own margin against the cheapest Greek offer for the same SKU.
Tracking a category over time. Store sku_id and price_from on a schedule. The SKU id does not change, so a diff is an exact join and price moves are unambiguous. fetched_at tells you when each row was captured.
Finding what is worth stocking. reviews_count is the closest public proxy for how much a product actually sells; rating tells you whether the listing is healthy. A product with 13 reviews at €1055 behaves differently from one with none.
Catalogue building. Title, image, price, rating and URL on every row, about 50 rows per request, no per-product fetch. Feed the result into a sheet, a warehouse table or a feed generator.
Competitor monitoring for Greek retailers. Run the category you sell in and see which shop holds the floor price this week.
Skroutz scraper compared with other options
Checking Skroutz by hand works for one product. It stops being practical at twenty, and by the time the spreadsheet is filled the prices have moved. This actor returns the same listings as structured rows, keyed by SKU id.
Skroutz's own developer documentation (developer.skroutz.gr) is aimed at shops that publish their own data to Skroutz. It is not a catalogue export: it will not hand you the competing offers for a category you choose. If you need the price comparison itself, you need a scraper.
Writing your own crawler is the usual alternative — several public Scrapy projects exist. That route means maintaining selectors against a site that changes its markup, deciding what counts as a real product page, deduplicating across pages and rebuilding pagination whenever it breaks. Here the parsing, deduplication, pagination and failure reporting are done for you and priced per row.
Other Skroutz actors in the Store cover the same site. Differences worth checking before you buy: whether you get the market floor price or a per-shop offer list, whether category pagination continues past one page, whether empty results are charged, and whether the run reports success on data rather than on an HTTP status code. Several of them advertise price history or a full per-shop offer list, which this actor does not produce: it returns the current snapshot — the lowest price Skroutz shows right now, with rating, review count and SKU id — and you build the series by running it on a schedule.
Generic scraping services give you a raw page per request that you still have to parse, deduplicate and price-match yourself. Here the JSON-LD product list is already turned into rows, and a run that never sees a product list is reported as such instead of returning an interstitial page as if it were data.
Pricing
| Event | Price | When |
|---|---|---|
run_start | $0.0005 | Once per run, including runs that return nothing |
product | $0.003 | Per product row delivered |
A search that returns 52 products costs $0.0005 + 52 × $0.003 = $0.1565. A category run of 600 products costs $0.0005 + 600 × $0.003 = $1.8005. An empty result costs only the start fee, so a search that finds nothing is not a bill. Free-plan runs are capped at 10 products, and those ten are the only ones charged for.
FAQ
Is there a Skroutz API?
Skroutz publishes developer documentation for shops that list their own products. It does not offer a public export of the comparison catalogue, so a scraper is the practical route to category-wide prices. You can also call this actor itself as an API: start a run through the Apify API with your input and read the dataset back.
Why does a search stop after one page?
Skroutz answers every pagination parameter on a search URL with the same first page. Walking it would bill you for duplicates. Pass a category URL when you need more than about 52 products; category URLs page deeper and the run reports paginates: true when that happened.
What happens when a search has no hits?
The run succeeds with zero product rows and a no_results note. You are not charged per product — only the $0.0005 start fee applies.
Can I get Skroutz price history?
Not from one run. This actor returns the current snapshot — the lowest price Skroutz compares right now, with rating, review count and fetched_at — not a stored series. Skroutz publishes no public export of its catalogue either (see the first question), so there is no history endpoint to call. To build a series, run the same url or query on a schedule and keep sku_id, price_from and fetched_at: the SKU id is stable across runs, so each run joins onto the one before it and a price move is unambiguous. The comparison section above says which other Store actors advertise a history they can only produce the same way.
Is brand always empty?
Frequently. Skroutz's product list does not carry a brand for most rows, so brand comes back null unless the listing publishes one. title normally contains the brand name as text, which is what most buyers match on.
Do I need a proxy?
Not by default. Skroutz is reachable from an ordinary connection with the right request shape, and use_proxy starts off. Turn it on only if your own runs start coming back empty; the actor then fetches through an alternative connection.
How do I export the data to CSV or Excel?
Open the run's dataset in the Apify console and choose JSON, CSV, Excel or another format, or fetch the items through the Apify API. The sku_id column is the one to join on when you export several runs.
Will I be charged for an empty dataset?
Only the run-start fee of $0.0005 applies. Product charges are counted per delivered row, so a run without products has no product charges.