Zid Scraper - Saudi Store Product & Price Tracker (SAR)
Pricing
from $1.75 / 1,000 product scrapeds
Zid Scraper - Saudi Store Product & Price Tracker (SAR)
Zid scraper: <store>.zid.store addresses to one row per product with SAR price, sale price, discount amount and percent, on-sale flag, SKU, categories and product link. For Saudi competitor catalogue and price watching. Residential proxy required.
Pricing
from $1.75 / 1,000 product scrapeds
Rating
0.0
(0)
Developer
Superslow Sloth
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Zid scraper: Saudi store product and price tracker (SAR)
This Zid scraper reads the whole product catalogue of any Zid
store (the Saudi store builder; stores live at <name>.zid.store) and returns
one flat row per product: the price in SAR, the sale price, the discount in
riyals and percent, an on-sale flag, SKU, categories and the product link. Use
it as a Saudi competitor catalogue and price watch: give it a list of
competitor stores, run it on a schedule and diff the dataset to see which
products were added, repriced or put on sale since last week.
No account, no API key, no login, no browser. One request returns 24 products. It needs the Apify RESIDENTIAL proxy (see below): the datacenter proxy is refused.
Input
| Field | Notes |
|---|---|
storeUrls | One or more Zid stores, one per line. Any of: the link (https://oav.zid.store, a link to any page of the store works, only the host is used), the address (alamirah-sa.zid.store) or just the store name (oav). Each store's whole catalogue is read. A store that does not exist fails at no charge. |
maxItems | Products to read per store (default 100, up to 10,000). Zid lists 24 per page. |
proxyConfiguration | Apify RESIDENTIAL proxy by default. Leave it. |
Only stores at <name>.zid.store are supported. A store on a custom domain
(one a merchant has moved to its own domain, shop.example.com) is refused
with an input error before the run starts and before anything is charged: no
Zid store on a custom domain could be found to measure, so the actor does not
claim to read them. Use the store's
<name>.zid.store address instead (it normally keeps working next to a custom
domain; the actor cannot check that for you).
Example input:
{"storeUrls": ["https://oav.zid.store", "alamirah-sa.zid.store"],"maxItems": 300}
Output
Prices are numbers in the store's currency; currency is SAR on every row
measured.
| Field | Notes |
|---|---|
store | The store's host (oav.zid.store), so rows from several stores in one dataset can be told apart. |
id | Zid's product id (a UUID string), unique within a store. |
parent_id | The parent product's id when the entry is a variant. Null on all 326 products measured; the catalogue lists parent products only. |
name | The product name as the merchant wrote it (Arabic, English, both, or a bare number), surrounding spaces trimmed. |
sku | The merchant's stock-keeping code. Null if absent. |
currency | SAR on every row measured; passed through as the store sends it. |
price | The regular price. When the product is discounted this is the price before the discount. Null if the page sends none. |
sale_price | The discounted price. Null when the product is not discounted, which is most of them (279 of 326 on the two stores measured). |
on_sale | True when sale_price is below price; False when there is no lower sale price; null only if price is missing. |
discount_amount, discount_percent | price minus sale_price in riyals, and the same as a percent of price to two decimals (490 to 295 is 195.0 and 39.8). Null unless both prices are present and the sale price is lower, never 0. |
categories | The names of the categories the product is filed in, as the merchant wrote them (often bilingual: العبايات | abayas). Empty list if none (44 of 326 products). |
url | The product page link, taken from the store page's own list. Null if the page did not carry one that lines up with the products. |
Example row (real values, 2026-10-19):
{"store": "oav.zid.store","id": "d4f75c78-d15c-451a-addf-a21b7bcf2219","parent_id": null,"name": "29","sku": "Z.1764700864734276","currency": "SAR","price": 770.0,"sale_price": null,"on_sale": false,"discount_amount": null,"discount_percent": null,"categories": [],"url": "https://oav.zid.store/products/29"}
Honest nulls
A field the page did not send is null, never 0. Two of the 326 products
measured were sent with a price of 0.0 (one per store, probably unpriced
items); they are returned as sent, because the store said it, and are not
turned into nulls or dropped.
- No stock, images or descriptions. The catalogue list does not carry them; this is a price and catalogue watch, not a full product export.
- No variants as rows. Only parent products are listed (
parent_idwas null on every row). - Prices as the store lists them. The actor does not say whether a store shows prices with or without VAT; Zid does not say in the list.
Pricing
Pay per event:
- $0.002 per run (
actor-start), charged only after your input is validated, so a run that fails on bad input costs nothing. - $0.00175 per product row written (
product-scraped), i.e. $1.75 per 1,000 products. Products that are not written are not charged.
Proxy: residential only
Zid stores sit behind Cloudflare. When this actor was built, every request from
an Apify datacenter address was refused with HTTP 403 and Cloudflare's "Just
a moment" page, while the residential group read every page (8 of 8, then 6
of 6 requests). The default input therefore selects RESIDENTIAL. If you switch
to the datacenter proxy, or no proxy, expect every page to fail; the run logs a
warning and fails with the refusal message rather than returning empty rows.
How it fetches
It reads the product list a Zid store page embeds for its own analytics (the
all_products argument of zidTracking.__internal.sendGaProductsViewItemsList)
instead of the theme's HTML cards, so it does not depend on the store's theme:
the same eight fields were found on two stores with different themes
(oav.zid.store, alamirah-sa.zid.store; 14 pages, 326 products). The product
link comes from the page's schema.org product list, matched to the products by
place and name.
Things worth knowing, all measured on 2026-10-19:
- 24 products per page; a page past the end is HTTP 404. Reading stops there. That is the end of the catalogue, not an error. A store that does not exist is also a 404, but with a different body, and fails that store.
- Pages do not overlap, and a product seen twice in one walk is written and charged once.
- A refusal is retried from a fresh address. HTTP 403, 429, 5xx, a Cloudflare "Just a moment" page (even with a 200) or a dropped connection rotates the proxy exit and retries. A store whose pages keep being refused fails with the reason, and what was read before stays in the dataset.
- A search or page with no product list reads as a store with no products and costs nothing.
- Depth. At most 10,000 products per store are read (417 pages).
If Zid changes its page data, the run fails with a message or returns fewer fields as nulls instead of inventing values.