# Paris.cl Scraper - Chile Product Prices, Offers & Card Prices (`superslowsloth/parischile-products`) Actor

Paris.cl scraper: paris.cl category pages (Chile) to one row per product with price, list price and Paris card (Tarjeta Cencosud) price in CLP, percent off, brand, seller, rating, reviews and promo tags. For Chilean retail price and promotion watching.

- **URL**: https://apify.com/superslowsloth/parischile-products.md
- **Developed by:** [Superslow Sloth](https://apify.com/superslowsloth) (community)
- **Categories:** E-commerce, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 product scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Paris.cl scraper: Chile product prices, offers and Paris card prices

This Paris.cl scraper reads the category pages of [paris.cl](https://www.paris.cl),
Chile's Paris department store, and returns one flat row per product: the **price
in Chilean pesos**, the **list ("normal") price**, the **Paris card (Tarjeta
Cencosud) price**, the percent off, the campaign tags (instalments without
interest, free delivery), brand, seller, rating and review count, colour and size,
the product link and the photo. Run it on a schedule and diff the dataset to get a
**Chilean retail price and promotion watch**: which iPhone, TV or sofa dropped,
which went on offer, and how much lower the Paris card price is.

No account, no API key, no login, no browser. One request returns one category's
first 30 products.

### Input

| Field | Notes |
|---|---|
| `categories` | One or more Paris categories, one per line: the path below paris.cl (`tecnologia`, `electro/television`, `mujer`) or the page URL (`https://www.paris.cl/electro/audio/audifonos/`). Up to 200. Product pages (ending `.html`) and the search page are not supported. |
| `maxItems` | Stop after this many products across all categories (default 100, up to 6,000). A category page lists 30, so 30 reads one category. |
| `proxyConfiguration` | Apify proxy by default; a refused request is retried from a fresh address and, after three refusals in a row, through the residential proxy. Switch the proxy off, or supply your own, to use exactly that. |

Example input:

```json
{
  "categories": ["tecnologia", "electro/television", "electro/audio/audifonos"],
  "maxItems": 90
}
```

A product that two categories both list is returned once, under the first.

### Output

Prices are whole Chilean pesos as integers; `currency` is `CLP`. **One row is one
product** as the category page lists it, i.e. its main variant: a shirt sold in
twelve sizes is one row, and `variant_count` says how many other variants exist.
`product_id` is the unique key within a run.

| Field | Notes |
|---|---|
| `category`, `position` | The category the row was read from and the place in its page, counting from 1. Paris' default order ("relevance") drifts a little between requests. |
| `product_id`, `sku`, `name`, `brand` | Paris' id for the product (the number or code that ends its address), the sku of the main variant, the name and the brand as Paris shows them. |
| `url`, `image_url` | The product page (`https://www.paris.cl/<name>-<id>.html`) and its first photo. |
| `currency` | `CLP`. |
| `price` | What the shopper pays today without the store card: the offer price when there is one, else the list price. |
| `list_price` | Paris' regular (list, "normal") price. **Null when the page shows none.** |
| `card_price` | The price with Paris' store card (Tarjeta Cencosud). **Null when the product has none**: 20 of the 30 products of `tecnologia` and 66 of the 150 read while building this actor had one. |
| `on_sale`, `discount_percent`, `card_discount_percent` | True when `price` is below `list_price` (false when equal, null when there is no list price), and how far `price` and `card_price` are below `list_price` in percent (`10.53` is 10.53% off), as Paris states them. It is what the page shows, not a comparison against any price history. The percentages are null when the product has no offer or card price. |
| `promo_tags` | The campaign tags Paris attaches to the product, as sent (`tag-10-cuotas-sin-interes-7`, `tag-despacho-gratis-sobre-19990-1P-13`). They name promotions such as instalments without interest or free delivery; the page does not say what each one is worth. An empty list when there are none. |
| `rating`, `review_count` | The average star rating (1 to 5, two decimals) and the number of reviews. **Rating is null for a product with no reviews**, and `review_count` is then 0. |
| `seller` | `Paris` for Paris itself, otherwise the marketplace seller's name. |
| `color`, `size`, `variant_count` | The colour and size of the main variant (size is null on products that have none) and how many other variants the product has. |
| `category_total`, `scraped_at` | How many products Paris says the whole category holds (47201 for `tecnologia` on 2026-11-05; the page lists only the first 30), and when the row was read, UTC. |

Example row (real values, 2026-11-05, `tecnologia`):

```json
{
  "category": "tecnologia",
  "position": 2,
  "product_id": "837803999",
  "sku": "837803999",
  "name": "iPhone 16 128GB Negro Liberado",
  "brand": "Apple",
  "url": "https://www.paris.cl/iphone-16-128gb-negro-liberado-837803999.html",
  "image_url": "https://cl-dam-resizer.ecomm.cencosud.com/unsafe/adaptive-fit-in/792x1068/paris/837803999/variant/images/2cf11c09-019c-4272-9e00-a3c043f3c4ec/837803999-0000-001.jpg",
  "currency": "CLP",
  "price": 849990,
  "list_price": 949990,
  "card_price": 799990,
  "on_sale": true,
  "discount_percent": 10.53,
  "card_discount_percent": 15.79,
  "promo_tags": [
    "tag-10-cuotas-sin-interes-7",
    "tag-10-cuotas-sin-interes-10",
    "tag-10-cuotas-sin-interes-8",
    "tag-despacho-gratis-sobre-19990-1P-13"
  ],
  "rating": 4.44,
  "review_count": 45,
  "seller": "Paris",
  "color": "Único Color",
  "size": null,
  "variant_count": 0,
  "category_total": 47201,
  "scraped_at": "2026-11-05T09:15:42Z"
}
```

#### Honest nulls, and what the page does not carry

A field the page did not show is `null`, never `0` or `""`; `promo_tags` is an empty
list when a product has none.

- **30 products per category address, no second page.** Paris' category page shows
  the first 30 products and loads more from the browser. Asking the page for
  `?page=2&sortby=relevance` (the address its own "load more" link carries), or for
  another `sortby`, returned the first page again (measured from the Apify platform,
  2026-11-05), so this actor cannot page. List several subcategories
  (`electro/television`, `electro/audio`, `electro/audio/audifonos`) to watch more
  products: each is its own 30.
- **Order is Paris' "relevance"**, which moves between requests; sort the dataset
  by `price` or `discount_percent` yourself.
- **Rows read from the schema.org copy.** Every page carries its 30 products twice,
  in the page's own data and as schema.org markup. If Paris changes the first, the
  actor reads the second, which has the name, link, photo, brand, offer price and
  rating but no list price, card price, seller, colour, size or tags: those columns
  are null and the run log says how many pages were read that way.
- **A category Paris does not have** is HTTP 404 and is skipped at no charge.

### 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.0021** per product written (`product-scraped`), i.e. $2.10 per 1,000
  products. A row that is not written is not charged: a product already returned
  for an earlier category, an empty category and a category that fails are free.

### How it fetches

paris.cl is a Next.js site behind CloudFront and AWS WAF, and a category page is
2.8 to 5.1 MB of HTML. From the machine this actor was built on every request, static files included, was answered HTTP 405
("Human Verification"). From inside the Apify platform, with a Chrome TLS
fingerprint, the page came back on 12 of 31 datacenter-proxy requests (the rest HTTP
403 from CloudFront) and 19 of 31 residential ones (most of the rest HTTP 405).
The actor therefore starts on the Apify datacenter proxy, retries each refused
request from a fresh address, and after three refusals in a row continues through the
residential proxy (four tries) and stays there. A refusal page served with HTTP 200 is
treated as a refusal as well.

The products are read from the page's own data (`productData`: `regular` and `offer`
prices and the `paymentMethod` card price, all `centAmount` in whole pesos), not
from the page's visible HTML. If Paris changes the page the run fails with a message,
or reads the schema.org copy as described above, instead of returning empty rows.

# Actor input Schema

## `categories` (type: `array`):

Paris.cl categories to read, one per line: the path below paris.cl (tecnologia, electro/television, mujer) or the page URL (https://www.paris.cl/electro/audio/audifonos/). Each category page lists its first 30 products and has no second page, so for a bigger watch list several subcategories (up to 200). A product already returned for an earlier category is returned once. Product pages (ending .html) and the search page are not supported.

## `maxItems` (type: `integer`):

Stop after this many products across all categories. One category page lists 30 products, so 30 reads one category; up to 6,000 (200 categories) are accepted.

## `proxyConfiguration` (type: `object`):

Apify proxy (automatic datacenter exits) is the default. paris.cl sits behind CloudFront and AWS WAF, which refused about three in five datacenter requests and two in five residential ones from the Apify platform when this actor was built; the actor retries each refused request from a fresh address and, after three refusals in a row, continues through the residential proxy. Switch the proxy off, or supply your own proxies, to use exactly that and nothing else.

## Actor input object example

```json
{
  "categories": [
    "tecnologia"
  ],
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "categories": [
        "tecnologia"
    ],
    "maxItems": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("superslowsloth/parischile-products").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "categories": ["tecnologia"],
    "maxItems": 30,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("superslowsloth/parischile-products").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "categories": [
    "tecnologia"
  ],
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call superslowsloth/parischile-products --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,superslowsloth/parischile-products"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MspDr5cLiuPwcyydh/builds/pAGFjXVQLIvhuOCO9/openapi.json
