By the end of this tutorial, you will have a Python script that turns a chileautos.cl search into structured JSON: one row per listing with price and currency, model year, mileage in kilometres, fuel, transmission, body type, region, and whether the seller is a dealer or a private seller.
Chileautos lists cars, motorcycles, trucks, machinery and other vehicles for sale in Chile. Copying them by hand means paging through search results 18 listings at a time, and in October 2026 testing the site answered plain, datacenter and residential connections with a bot-challenge page.
We will use Python and the Apify Actor Chileautos Scraper (reventadata/chileautos-scraper), which reads the site through Apify's Unblocker proxy by default. The sample rows in this guide come from a capture dated 2026-10-21, parsed with the Actor's own code.
⏱️ Time estimate: About 30 minutes.
Prerequisites
To follow this tutorial, you will need:
-
Python 3.11+ installed locally (
apify-client3.x requires it). - The Apify API client for Python.
- An Apify account and API token.
Sign up for an Apify account, then copy your API token from API & Integrations in Apify Console. Install the client:
pip install "apify-client~=3.0"
The code loads the token from an environment variable:
export APIFY_API_TOKEN="your_apify_token_here"
What you'll achieve
You will turn a chileautos.cl search into rows you can load into a spreadsheet or database: listing id and link, title and trim line, make and model, model year, price with its currency, odometer in kilometres, fuel, transmission, body type, region, seller type, and the dealer's business name when the seller is a dealer.
Note on data boundaries: The Actor reads search result cards only. It does not open listing detail pages, so descriptions, full photo galleries and seller phone numbers are not in the rows. Private sellers appear only as "Particular" on the site, so no personal name is read.
Example use case: You want the Toyota cars listed on chileautos.cl, newest model year first. Setting vehicleType: "autos", make: "Toyota" and sortBy: "year-desc" asks the site for exactly that search, and the rows tell you which listings come from dealers and which from private sellers.
Step 1: Access Chileautos Scraper
Go to the Chileautos Scraper page on Apify Store to try it. The page shows the input fields, an output example and the README.
You can run it from Apify Console with Try for free. In this tutorial we start it from Python instead, so the same script can run again tomorrow.
Step 2: Configure the search
There is no free-text keyword box. You describe the search with the same filters the site offers: vehicleType, make, model, condition, region, sellerType, fuel, price, year and mileage ranges, and sortBy. The Actor builds the site's own search from these fields, so the filtering happens on chileautos.cl before any row reaches you.
Spell make and model as chileautos.cl does (for example Toyota and Hilux). A model needs a make; without one the Actor stops before fetching anything.
In Python, we create the client and the input:
import os
from apify_client import ApifyClient
# 1. Initialize ApifyClient with token from environment
client = ApifyClient(os.environ["APIFY_API_TOKEN"])
# 2. Define the search: Toyota cars, newest model year first
run_input = {
"vehicleType": "autos",
"make": "Toyota",
"sortBy": "year-desc",
"maxItems": 20,
}
(Note: the sample rows in this guide come from page 1 of this same search, Toyota cars sorted by year, newest first, captured on 2026-10-21. That page held 18 listings.)
Step 3: Optional settings and filters
Every field below except the two keyword lists and maxItems is sent to chileautos.cl as part of the search. The keyword lists are applied by the Actor after each page is read.
| Parameter | Type | Default | Description |
|---|---|---|---|
vehicleType |
string | "all" |
all, autos, motos, camiones, buses, maquinarias, casas-rodantes, nautica, aereos. |
make / model
|
string | empty | Brand and model as the site spells them. model needs make. |
condition |
string | "any" |
any, new, used. |
region |
string | "any" |
One of Chile's 16 regions, for example metropolitana or valparaiso. |
sellerType |
string | "any" |
any, dealer, private, verified-private. |
fuel |
string | "any" |
any, gasoline, diesel, electric, gas, hybrid, other. |
minPrice / maxPrice
|
integer | empty | Listed price range. The site compares the listed number whatever its currency. |
minYear / maxYear
|
integer | empty | Model year range. |
minKm / maxKm
|
integer | empty | Odometer range in kilometres. |
sortBy |
string | "featured" |
One of 9 site sort orders, for example price-asc or year-desc. |
maxItems |
integer | 100 |
Total listings to save. |
includeKeywords / excludeKeywords
|
array | empty | Keep or drop rows by words in title, trim, make, model, body type or dealer name, ignoring case and accents. |
A few practical notes:
-
The fixed lists are checked before the run starts. A value outside a list (a misspelt
region, say) is refused by the platform and the Actor is not started. -
featuredis random per request. It is the site's default sort; the Actor removes duplicate listing ids, but use another sort when you want a stable order.
Step 4: Run the Actor
Start the run and wait for it with client.actor("reventadata/chileautos-scraper").call(run_input=run_input):
# 3. Start the Actor run and wait for it to complete
print("Starting Chileautos extraction...")
run = client.actor("reventadata/chileautos-scraper").call(run_input=run_input)
if run is None or run.status != "SUCCEEDED":
status = run.status if run else "unknown"
raise SystemExit(f"Run did not succeed (status: {status}).")
# 4. Fetch the resulting dataset items
dataset = client.dataset(run.default_dataset_id).list_items().items
print(f"Extraction complete! Retrieved {len(dataset)} listings.\n")
Behind the scenes:
- The Actor sends the search to chileautos.cl through Apify's Unblocker proxy (the default). In October 2026 testing, no proxy, a datacenter proxy and a residential proxy all got the bot-challenge page; Unblocker reached the result pages.
- It reads the result pages in order, about 18 listings per page, and saves one row per listing.
- The site serves at most 50 pages per search, about 900 listings. When
maxItemsasks for more and the search is bigger than that, the Actor cuts the search into price ranges and reads each one.
Step 5: View and download results
Once the run finishes, print a short summary of each row:
for item in dataset:
price = item.get("price")
km = item.get("odometerKm")
mileage = f"{km:,} km" if km is not None else "not stated"
print(f"Listing: {item.get('title')} {item.get('trim') or ''}".rstrip())
if price is None:
print(" Price: not listed")
else:
print(f" Price: {price:,} {item.get('currency')}")
print(f" Mileage: {mileage}")
print(f" Seller: {item.get('sellerType')} ({item.get('sellerName') or 'no dealer name'})")
print(f" Region: {item.get('region')}")
print("-" * 50)
Apify datasets also export as JSON, CSV, XML, Excel, HTML table, RSS or JSONL.
Here is one row, a sample from a capture dated 2026-10-21, parsed with the Actor's own code (a real run also adds scrapedAt, the time the row was saved):
{
"id": "CL-AD-21005905",
"url": "https://www.chileautos.cl/vehiculos/detalles/2026-toyota-yaris-1-5-e-4x2-sdn-mt-4p/CL-AD-21005905/",
"title": "2026 Toyota Yaris",
"trim": "1.5 E 4X2 SDN MT 4P",
"make": "Toyota",
"model": "Yaris",
"year": 2026,
"price": 12800000,
"currency": "CLP",
"odometerKm": 3700,
"fuelType": "Bencina",
"transmission": "Manual",
"bodyType": "Sedán",
"fuelEconomy": "16,9 Kms/Lt.",
"condition": null,
"sellerType": "private",
"sellerName": null,
"region": "Metropolitana de Santiago",
"imageUrl": "https://chileautos.pxcrush.net/chileautos/cars/private/azlhefud9wald3p8l8dwrt5uu.jpg?pxc_method=fitfill&pxc_bgtype=self&pxc_size=432,288",
"imageCount": 8,
"badges": [],
"page": 1
}
Understanding your results
The key fields:
-
id: chileautos.cl listing id. In the 18-row sample, private listings startCL-AD-and dealer listingsCP-AD-orGI-AD-. -
title/trim: the headline (year, make, model) and the version line under it. -
price/currency: the listed number and the currency printed next to it (all 18 sample rows were CLP; the site also lists in USD).nullwhen no price is listed. -
odometerKm: kilometres as typed by the seller. 13 of the 18 sample rows had none: all 13 were new cars at dealers. -
fuelType,transmission,bodyType: as the site writes them, in Spanish (Bencinais gasoline). -
condition:neworusedfor dealers;nullfor private sellers, which the site does not label. -
sellerType/sellerName:dealer,privateorverified-private; the dealer's business name, ornull. -
badges: promotion badges on the card. 15 of the 18 sample rows showedPremium.
In the sample page, 15 rows came from dealers, 3 from private sellers and 0 from verified private sellers.
Pro tips
-
Mind the 900-row ceiling. The site stops at 50 pages of 18 listings per search. The capture's Toyota search had 2,382 results over 133 pages, so a
maxItemsabove about 900 makes the Actor read it in price slices. A listing with no price cannot be reached by a price slice. -
Narrow on the site, not afterwards.
region,sellerType,fuel,conditionand the ranges go into the site's search, so you only read pages you want. -
Price ranges compare raw numbers. A listing priced in USD is compared by its dollar amount, as the site does. Check
currencybefore comparing prices across rows. -
Use the keyword lists for trims.
includeKeywords: ["4x4"]keeps rows whose title, trim, make, model, body type or dealer name contains "4x4", ignoring case and accents. -
Start small. Begin with
maxItems: 20to check the fields on one page of results, then raise it.
Troubleshooting
- 0 rows saved: a run that is blocked or cannot read a page ends FAILED. A search that loads normally but matches nothing ends SUCCEEDED with an empty dataset and a status message saying so; loosen your ranges or check the make spelling.
- Run FAILED with "The site did not apply make=...": chileautos.cl answers a malformed make or model term (not a misspelling, which returns no results) with every vehicle. The Actor checks page 1 and stops rather than export the wrong cars. Copy the spelling from chileautos.cl.
-
Run not started: a value outside a fixed list (
vehicleType,region,sortBy, ...) is refused by the platform before the run starts. -
Reading the log: the run's summary line reads
Run finished: N rows pushed. Rejections: .... Read it from Python withclient.log(run.id).get(). For help, use the Store page.
Pricing and next steps
For current pricing and details, see the Store page.
To repeat a search, save it as a task and add an Apify schedule, which runs Actors and tasks on a cron expression. A webhook on ACTOR.RUN.SUCCEEDED sends the run object, including defaultDatasetId, to your endpoint.
Links:
Which vehicles or regions are you planning to track on Chileautos? Drop a comment! 💬
Top comments (0)