Sitemap
ReventaData

ReventaData

Web scraping, API reverse-engineering & automated data feeds at scale. Building turnkey marketplace scrapers on Apify: apify.com/reventadata

How I Turned Chileautos Listings into JSON in Minutes Using Python (Step-by-Step)

9 min read1 day ago

--

Press enter or click to view image in full size

I build and publish scrapers on the Apify Store, and this one reads Chile’s vehicle classifieds site: Chileautos Scraper. Here is how to run it from Python.

chileautos.cl lists cars, motorcycles, trucks, buses, machinery and more for sale across Chile. Its search pages show 18 listings at a time, and any one search stops after 50 pages. Comparing prices or mileage across a make means clicking listing after listing and copying numbers into a spreadsheet.

A home-made scraper has its own problem. In October 2026 testing, the site answered a plain connection, a datacenter proxy and a residential proxy with a bot-challenge page instead of results.

So I built a cloud Actor for it: Chileautos Scraper (reventadata/chileautos-scraper). You describe the search with the same filters the site offers, and it returns one clean row per listing. It reads the site through Apify's Unblocker proxy by default, the only connection that reached the result pages in that same testing.

In this tutorial, you will set up the search, run it from Python and read the rows. I did not run it for this guide: the rows below are a sample from a capture dated 2026–10–21, parsed with the Actor’s own code.

Why I needed this solution

A chileautos.cl search is built for a person browsing, not for a table. The numbers you want (price, year, kilometres, fuel, region, dealer or private seller) are all on the result cards, but spread over pages.

Here is what makes doing it by hand slow:

  • Paging: 18 listings per page and 50 pages per search, so about 900 listings is the most one search shows.
  • Mixed sellers: dealers and private sellers sit side by side, and only the dealer cards say whether the car is new or used.
  • Mixed currencies: most prices are in Chilean pesos, but the site lists in US dollars.

The idea is simple and practical: give the Actor a make, model, region or price range, and get JSON that exports to CSV or Excel, with numbers as numbers. That is what this Actor does, and the rest of this post shows it.

What you’ll need

  • An Apify account: sign up on apify.com; your runs and their datasets are kept there.
  • Your Apify API token: on the API & Integrations page in Apify Console.
  • Python 3.11 or newer, with the official apify-client library (version 3.x needs 3.11+).
  • Time required: about 30 minutes to read and run the code. Most of it is setup; the script itself is four short blocks.
  • No scraping code of your own: the Actor does the fetching; you write a few lines to start it and read the rows.
  • Pricing: For current pricing and details, see the Store page.

What you’ll accomplish

By the end, a chileautos.cl search becomes a list of rows like this, one per listing:

  • Identity and link: id, url, title and trim (the version line, such as "1.5 E 4X2 SDN MT 4P").
  • The car: make, model, year, odometerKm, fuelType, transmission, bodyType.
  • The price: price and currency (CLP, USD, UF or EUR).
  • The seller: sellerType (dealer, private or verified private), sellerName for dealers, and condition (new or used) where the dealer states it.
  • Where: region.

You can then sort, filter and chart those rows in any spreadsheet, or load them straight into a database.

Step-by-step walkthrough

Step 1: Get started with Chileautos Scraper

First, open the Chileautos Scraper page on Apify Store. It shows the input fields, an output example and the README. Apify Console is your workspace: it is where runs, datasets and your API token live.

Install the Apify Python client:

pip install "apify-client~=3.0"

Then set your token in your shell:

export APIFY_API_TOKEN="your_apify_token_here"

💡 Tip for Step 1: Keep the token in the environment, as above, not in the script. The code in this post reads it from APIFY_API_TOKEN, so you can share the script without sharing your token.

Step 2: Tell the tool what you want

There is no keyword box. Instead, you pick from the filters chileautos.cl itself has, a bit like ticking boxes on the site’s search page. I used Toyota cars, sorted with the 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.)

What each field does:

  • vehicleType: autos is cars; others include motos, camiones (trucks) and maquinarias (machinery).
  • make: the brand, spelled the way chileautos.cl spells it.
  • sortBy: the site's own sort orders; year-desc puts the newest model years first.
  • maxItems: how many listings to save in total.

💡 Tip for Step 2: The capture’s Toyota search had 2,382 results over 133 pages, far beyond what one search shows. Keep maxItems small while you test.

Step 3: Fine-tune your settings (optional)

You can narrow the search further, and all of these go to the site as part of the search:

  • region: one of Chile's 16 regions, such as metropolitana or valparaiso.
  • sellerType: dealer, private or verified-private.
  • condition: new or used.
  • fuel: gasoline, diesel, electric, gas, hybrid or other.
  • minPrice / maxPrice, minYear / maxYear, minKm / maxKm: ranges.

Two more lists are applied by the Actor after each page: includeKeywords keeps rows that contain every word you give, and excludeKeywords drops rows that contain any of them. Both look at the title, trim, make, model, body type and dealer name, and ignore accents and capital letters.

Get ReventaData’s stories in your inbox

Join Medium for free to get updates from this writer.

The defaults work for a first run: whole country, any seller, any fuel, new and used, the site’s featured order. A value outside these lists is refused before the run starts.

💡 Tip for Step 3: The price range compares the listed number whatever its currency, so a listing priced in US dollars is compared by its dollar amount. When I read the capture’s rows, all 18 were in CLP, but check currency before you compare prices across a bigger dataset.

Step 4: Hit the Start button

Now start the run. From Python, call() starts the Actor in Apify's cloud and waits until it finishes:

# 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")

While you wait, here is what happens behind the scenes. The Actor sends your search to chileautos.cl through Apify’s Unblocker proxy, reads the result pages in order and saves each listing as a row. If you ask for more than one search can show (about 900 listings), it splits the search into price ranges and reads each one.

💡 Tip for Step 4: Keep the status check. A blocked run with no rows ends as failed, and the Actor stops if the site ignored your make or model, so your script hears about it instead of saving the wrong cars. A search matching nothing ends SUCCEEDED with an empty dataset: check the item count too.

Step 5: Check out your results

Once the run is done, print a short line per listing:

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)

Here is one full row, a sample from a capture dated 2026–10–21, parsed with the Actor’s own code (a real run 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
}

In plain words: a 2026 Toyota Yaris sedan from a private seller in the Santiago region, 12,800,000 Chilean pesos, 3,700 km on the clock. Bencina is Spanish for gasoline. condition is empty because private sellers' cards do not say new or used.

💡 Tip for Step 5: null means the card did not show that value; the Actor never fills a gap with 0. In the capture, 13 of the 18 rows had no odometer reading, so treat a missing mileage as unknown.

Step 6: Download and use your data

Apify datasets export as JSON, CSV, XML, Excel, HTML table, RSS or JSONL. CSV or Excel opens straight in a spreadsheet; JSON suits a script or database.

💡 Tip for Step 6: For the table later in this post, I grouped the 18 rows by model in Python and sorted the groups by lowest price.

The results that surprised me

These are the 18 rows on page 1 of the captured search (Toyota cars, newest first, 2026–10–21). One page is a sample, not the market, but it already shows a few things.

First, the sellers. 15 of the 18 listings came from dealers, 3 from private sellers and none from verified private sellers. Of the 15 dealer rows, 13 said new and 2 said used; the 3 private rows carry no condition at all.

Second, mileage. 13 of the 18 rows had no odometer reading: exactly the 13 new cars at dealers. The three private sellers did state one: 3,700 km, 7,900 km and 9,900 km.

Third, place. 15 rows were in the Metropolitana de Santiago region; the other three were in Bío Bío, Ñuble and Araucanía, and two of those three were the private sellers.

Fourth, the mix. All 18 were model year 2026 and priced in CLP, from 12,800,000 to 69,990,000. SUVs were 10 of the 18 rows, sedans 4 and pick-ups 4. Fuel: 9 gasoline, 7 diesel, 1 hybrid, 1 electric.

Finally, promotion: 15 of the 18 cards carried a Premium badge, which lands in the badges field. The 3 without one were the 3 private sellers.

Tips I learned along the way

  1. Copy the make and model from chileautos.cl. An unknown make returns no results. If the site ignores a malformed term, the Actor checks page 1 and stops rather than save the wrong cars.
  2. Pick a fixed sort for repeat runs. The default featured order is random per request, so two runs can list rows differently. year-desc or price-asc gives the same order each time.
  3. Mind the ceiling. One search shows at most about 900 listings. Above that, the Actor slices by price, and a listing with no price cannot be reached by a price slice.
  4. Use the keyword lists for versions. includeKeywords: ["4x4"] keeps rows with 4x4 in the title or trim, ignoring case.
  5. Schedule it. Save your input as a task and add an Apify schedule; schedules run Actors and tasks on a cron expression, a timetable format such as “every day at 8:00”.

What I built with this data

I grouped the 18 sample rows by model, sorted by lowest price:

Model Rows Lowest (CLP) Highest (CLP) Yaris 4 12,800,000 14,990,000 Raize 1 12,990,000 12,990,000 Yaris Cross 1 18,090,000 18,090,000 Rav4 3 24,300,000 25,990,000 Corolla Cross 1 26,500,000 26,500,000 Hilux 4 32,490,000 50,490,000 Bz4x 1 44,990,000 44,990,000 Land Cruiser 3 59,990,000 69,990,000

One pair stood out: the Yaris version “1.5 E 4X2 SDN MT 4P” appears twice, at 12,800,000 from a private seller (3,700 km) and at 14,990,000 from a dealer, listed as new.

Conclusion

Before: a site you page through 18 listings at a time. After: a few lines of Python and rows with price, currency, year, kilometres, region and seller type.

Start small: run the Toyota example with maxItems: 20, look at the fields, then change the make, region or price range. Tell me in the comments which Chileautos Scraper search you ran.

About the author: reventadata builds and maintains marketplace scrapers on the Apify Store.

👏 If this helped you, please clap and follow for more tutorials!

--

--