Complete Guide: How to Scrape Chileautos Vehicle Listings Using Python
Run the Chileautos Scraper Apify Actor from Python and get chileautos.cl prices, year, mileage, region and seller type as clean JSON rows.

This complete guide to Chileautos Scraper shows how to run a chileautos.cl scraper from Python through the Apify API and get back typed listing rows: price and currency, model year, mileage in kilometres, fuel, transmission, body type, region, seller type, and the dealer's business name where there is one.
Chileautos is a vehicle classifieds site for Chile. Its search covers cars, motorcycles, trucks, buses, machinery, motorhomes, boats and aircraft. Two things stand between a hand-written crawler and that data. First, in October 2026 testing the site answered plain requests, a datacenter proxy and a residential proxy with a bot-challenge page. Second, any single search stops at 50 pages of 18 listings, about 900 rows.
You will automate the extraction with the Chileautos Scraper Apify Actor (reventadata/chileautos-scraper). Prerequisites are minimal: Python 3.11+, the official apify-client package, and an Apify API token. Estimated time to complete: about 30 minutes. The sample rows in this guide are a sample from a capture dated 2026-10-21, parsed with the Actor's own code; this guide quotes no run.
TL;DR
In this tutorial, you'll learn to start the Chileautos Scraper Apify Actor from Python, wait for the run, and read its dataset. Key steps: install apify-client, export APIFY_API_TOKEN, describe the search with the site's own filters (vehicleType, make, region, sellerType, ranges, sortBy) in run_input, call the Actor, then read the items from run.default_dataset_id.
Expected outcome: a JSON list of chileautos.cl listings with price, currency, year, mileage and seller type, ready for a spreadsheet, database or analysis script.
The Actor is at apify.com/reventadata/chileautos-scraper.
Prerequisites and setup
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 first. Apify Console is the web interface where runs, datasets and tokens are managed; your token is on the API & Integrations page. Keep the token out of any file you commit: the snippets below read it from the environment, so the same script runs on a laptop, a server or in CI. The platform documentation starts at docs.apify.com.
Install the client:
pip install "apify-client~=3.0"
Set your API token in your environment:
export APIFY_API_TOKEN="your_apify_token_here"
Understanding Chileautos Scraper
How it works behind the scenes
- The site's own search. chileautos.cl loads its results from a search endpoint. The Actor sends each search there, built from your input fields, so make, model, region, seller type, fuel, condition and the price, year and mileage ranges are filtered by the site itself.
- Unblocker by default. In October 2026 testing, Apify's Unblocker proxy group reached the result pages, while the other connections got the challenge page on the site's HTML search page. It is the default
proxyConfiguration. - Pages and slices. The Actor reads result pages in order, about 18 listings each. The site serves at most 50 pages per search; when the search is bigger and
maxItemsasks for more than one search can return, the Actor cuts it into price ranges and reads each one. - Rows. Each listing card becomes one row. Duplicate listing ids are skipped.
Limitations to be aware of
- No free-text keyword search and no start URLs: you search with the filters.
- No detail pages: no descriptions, full galleries or phone numbers.
- Private sellers show only "Particular" on the site, so their rows carry no name.
Step-by-step walkthrough
Step 1: Initialize the client and define inputs
Create the client from your environment token and describe the search. This example asks for Toyota cars, newest model year first:
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.)
Two more configurations that use the same fields:
- Private sellers in the Valparaíso region:
{"region": "valparaiso", "sellerType": "private", "sortBy": "year-desc", "maxItems": 50}. - Used Toyota Hilux, 2018 to 2022, under 100,000 km:
{"make": "Toyota", "model": "Hilux", "condition": "used", "minYear": 2018, "maxYear": 2022, "maxKm": 100000, "maxItems": 100}.
Step 2: Trigger execution on Apify
.call(run_input=run_input) starts the run and waits for it to finish:
# 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")
Step 3: Iterate and process dataset items
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)
Step 4: Inspect a real row
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
}
Step 5: Export the data
Apify datasets export as JSON, CSV, XML, Excel, HTML table, RSS or JSONL, from Apify Console or through the API.
Understanding your data
Field by field:
id,url: listing id and link without the site's tracking query. In the sample page, private listings startCL-AD-, dealer listingsCP-AD-orGI-AD-.title,trim,make,model: the headline, the version line, and the make and model the site attaches to the listing.year,price: integers, ornullwhere the site stores 0.currencyis printed next to the price: CLP, USD, UF or EUR.odometerKm: kilometres as typed by the seller; sellers can mistype, so check outliers.fuelType,transmission,bodyType,fuelEconomy: as the site writes them, in Spanish.condition:neworusedfor dealers,nullfor private sellers.sellerType,sellerName:dealer,privateorverified-private, and the dealer's business name.region,imageUrl,imageCount,badges,page.
What the 18-row sample page shows: every row was model year 2026 and priced in CLP; 15 were dealers, 3 private sellers and 0 verified private sellers; 13 rows had no odometer reading; 15 carried a Premium badge.
Working with the API
call() holds the connection until the run ends and returns the Run object. For longer runs or a job queue, client.actor("reventadata/chileautos-scraper").start(run_input=run_input) returns as soon as the run is created; keep its id and read the run later. Either way, the dataset id is the run's default_dataset_id, and client.dataset(...).list_items().items returns the rows. list_items() makes one API call and may not return every item of a large dataset; iterate_items() makes as many calls as it needs to return them all.
Authentication is the API token from API & Integrations. Keep it in an environment variable, as the snippet does, and never in the code you commit.
For event-driven pipelines, add a webhook on the ACTOR.RUN.SUCCEEDED event. Apify then POSTs to your endpoint, and the payload's resource is the response of the Get Actor run API endpoint, which carries defaultDatasetId. Your handler reads the rows from that dataset without polling.
Error handling: a run that saves no rows ends FAILED when a page was blocked or could not be read, so check run.status before reading the dataset, as the snippet does. A search that loads normally but matches nothing ends SUCCEEDED with an empty dataset and a status message saying so, so check the item count too. A make or model term the site does not apply also ends the run FAILED with a message, and a value outside a fixed list (region, fuel, sortBy, ...) is refused before the run starts: the call returns an API error and the Actor is not started.
Scheduling: save an input as a task and attach an Apify schedule. Schedules run Actors and tasks at times set by a cron expression.
Advanced usage patterns
1. More than 900 rows from one search
The site stops at 50 pages per search. The captured Toyota search had 2,382 results over 133 pages. Ask for maxItems: 2500 and the Actor cuts the search into price ranges, each under the ceiling, and reads them one after another. A listing with no price cannot be reached by a price slice, so a very large run can miss those.
2. Several markets in one pipeline
The Actor takes one search per run. To compare regions or makes, start one run per input (with start()), keep a map from each run id to its input, then read each run's dataset.
3. Trim and dealer keywords
includeKeywords keeps rows whose title, trim, make, model, body type or dealer name contains every word given; excludeKeywords drops rows with any of them. Matching ignores case and accents. Example: includeKeywords: ["4x4"] with make: "Toyota" keeps rows with 4x4 in the title or trim.
4. Monitoring
Pair a schedule with a webhook on ACTOR.RUN.SUCCEEDED to load new rows, and one on ACTOR.RUN.FAILED to alert you when a run saves no rows because a page was blocked or could not be read, or gets bad input. A search that stops matching anything does not fire it, because that run ends SUCCEEDED with an empty dataset; check the item count or the status message instead.
Troubleshooting guide
- 0 rows saved: a blocked run or one that cannot read a page ends FAILED. If pages loaded normally and nothing matched, it ends SUCCEEDED with an empty dataset and a status message saying so: the filters were too narrow, or the make is one the site does not know (the site answers that with no results).
- Run FAILED, "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 on the site. The Actor compares page 1 with what you asked for and stops instead of exporting the wrong cars. Copy the spelling from chileautos.cl.
- "model needs make": the site only filters a model inside a make.
- Rows in a different order each run: the default
featuredsort is random per request. Useyear-desc,price-ascor another fixed sort. - A USD listing inside a CLP range: the site compares the listed number whatever the currency. Filter on
currencyafterwards. - Reading the log: the run's summary line reads
Run finished: N rows pushed. Rejections: .... From Python:client.log(run.id).get(). For help, use the Actor's Store page.
Best practices
- Filter on the site. Use
region,sellerType,conditionand the ranges rather than filtering rows afterwards; you read fewer pages. - Set
maxItemsto what you need. The default is 100; use 20 while you test. - Pick a fixed sort for repeat runs so two datasets line up.
- Keep currency in mind when you compare prices.
- Check outliers in
yearandodometerKm. Both are typed by sellers. - Schedule, don't loop. A schedule reruns a saved task on a cron expression.
- Start with the default proxy. Of the four connections tested in October 2026, only Unblocker reached the site; change
proxyConfigurationonly if you have measured another one yourself.
Pricing
For current pricing and details, see the Store page.
Conclusion and next steps
With Chileautos Scraper and the Apify Python client, a chileautos.cl search becomes a list of typed rows: price, currency, year, mileage, region and seller type. Start with a small maxItems, check the fields, then schedule the search and compare datasets over time.
Try Chileautos Scraper yourself and let me know what you build!
About the author: reventadata builds and maintains marketplace scrapers on the Apify Store.
Resources
About the author
- Hi, I’m the engineer behind ReventaData. I build automated web scrapers, reverse-engineer undocumented APIs, and design data pipelines on Apify that turn complex, unstructured websites into clean, reliable feeds. Here on Hashnode, I share practical tutorials on modern web scraping with Python, bypassing aggressive anti-bot protections (Cloudflare, Akamai, PerimeterX), and data pipeline automation, reverse-engineering hidden endpoints, and automating data extraction. Explore our turnkey scrapers: https://apify.com/reventadata
Comments
Join the discussionNo comments yet. Be the first to comment.




