# Kijiji Scraper — Canada Classifieds, Cars & Prices (`logiover/kijiji-scraper`) Actor

Scrape job postings for Belgium from Talent.com: title, hiring company, city, quick-apply flag, update recency and a description snippet. Keyless, no login. Export JSON, CSV or Excel.

- **URL**: https://apify.com/logiover/kijiji-scraper.md
- **Developed by:** [Logiover](https://apify.com/logiover) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Kijiji Scraper — Canada Classifieds, Cars & Prices

Export listings from **Kijiji**, Canada's largest classifieds site — price, mileage, transmission, fuel and location — to JSON, CSV or Excel. Keyless, no login.

### What does Kijiji Scraper do?

Kijiji renders its results server-side, so this Actor parses the cards directly and walks the pagination. No API key, no account, no cookies.

Kijiji is built with styled-components, which means **every class name carries a build hash** (`sc-ed38c1d6-3`) that changes when they deploy. Selectors pinned to a full class name break within weeks; this Actor matches the stable prefix instead.

The bigger trap is that price, mileage, transmission, fuel and city all render as sibling nodes sharing one class. Read them by index and the moment an ad omits its mileage, "Automatic" lands in the price column. This Actor classifies each value by its own pattern — a leading `$` is a price, a `km` suffix is mileage, a known gearbox word is transmission — so every column holds the right kind of value on every row.

Kijiji's own **price rating** ("Good price", "Above average") is captured as its own field, which is a ready-made signal for spotting underpriced stock.

### Who is it for?

- **Car dealers and resellers** hunting private-seller inventory across provinces.
- **Price analysts** building mileage-versus-price curves.
- **Rental and property researchers** tracking Canadian listings.
- **Arbitrage buyers** filtering on Kijiji's own price rating.
- **Marketplace builders** who need a Canadian feed.

### Use cases

- Compare asking prices for a model between Winnipeg, Saskatoon and Toronto.
- Filter to listings Kijiji itself flags as "Good price".
- Build a mileage-versus-price scatter for a model year.
- Track weekly supply in a category to time a purchase.
- Switch the category path to scrape rentals or jobs instead of cars.

### Why use this Actor?

- **Keyless** — no account, no token, no login.
- **Hash-proof selectors** — matches class prefixes, not build hashes.
- **Content-classified columns** — price, mileage, transmission and fuel never swap places.
- **Price rating included**, Kijiji's own valuation signal.
- **Any category** — cars, rentals, jobs, electronics, via one path input.
- **Numeric mileage and price** ready for sorting and charting.

### What data can you extract?

Every row carries the listing ID and URL, title, price in label and numeric form, Kijiji's price rating, mileage in label and kilometres, transmission, fuel, location and the thumbnail. Non-vehicle categories simply leave the vehicle-specific fields `null`.

### How to use it

1. Set the **category path** — copy it straight from the Kijiji URL.
2. Optionally add a keyword and price band.
3. Set **Maximum results** and run, then export JSON, CSV or Excel.

### Input example

```json
{
  "categoryPath": "b-cars-trucks/canada/c174l0",
  "minPrice": 5000,
  "maxPrice": 30000,
  "maxResults": 1000
}
```

### Notes and limits

- Vehicle fields (mileage, transmission, fuel) only appear in vehicle categories; elsewhere they stay `null` by design.
- Dealer ads sometimes show a with-taxes figure next to the asking price; the asking price is what lands in `priceAmount`.
- Prices are asking prices, not transaction prices.
- Seller contact sits behind a click on the listing page; this Actor returns the URL.
- You are responsible for how you use listing and seller data.

### FAQ

**Do I need a Kijiji account?**
No. Listings are public and this Actor needs nothing from you.

**Can I scrape apartments or jobs?**
Yes — change the category path; every Kijiji section works.

**What is the price rating?**
Kijiji's own assessment of the asking price against comparable listings. It is passed through as published.

**Will it survive a Kijiji redesign?**
It is built for that: selectors match class prefixes and values are classified by content, not position.

**How am I charged?**
Pay per result — you pay for the listings delivered.

# Actor input Schema

## `categoryPath` (type: `string`):

Kijiji URL path for the category and region, e.g. "b-cars-trucks/canada/c174l0", "b-apartments-condos/canada/c37l0", "b-jobs/canada/c45l0". Copy it from the Kijiji address bar.

## `query` (type: `string`):

Optional free-text filter inside the category.

## `minPrice` (type: `integer`):

Only return listings at or above this price. 0 disables the filter.

## `maxPrice` (type: `integer`):

Only return listings at or below this price. 0 disables the filter.

## `maxResults` (type: `integer`):

Stop after this many listings. The Actor walks pages until the target is met.

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

Kijiji serves plain HTML; the default datacenter proxy is enough.

## Actor input object example

```json
{
  "categoryPath": "b-cars-trucks/canada/c174l0",
  "minPrice": 0,
  "maxPrice": 0,
  "maxResults": 500,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `listingId` (type: `string`):

No description

## `title` (type: `string`):

No description

## `listingUrl` (type: `string`):

No description

## `priceLabel` (type: `string`):

No description

## `priceAmount` (type: `string`):

No description

## `currency` (type: `string`):

No description

## `priceRating` (type: `string`):

No description

## `mileageLabel` (type: `string`):

No description

## `mileageKm` (type: `string`):

No description

## `transmission` (type: `string`):

No description

## `fuel` (type: `string`):

No description

## `location` (type: `string`):

No description

## `imageUrl` (type: `string`):

No description

## `country` (type: `string`):

No description

## `source` (type: `string`):

No description

## `scrapedAt` (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 = {
    "categoryPath": "b-cars-trucks/canada/c174l0",
    "query": "",
    "minPrice": 0,
    "maxPrice": 0,
    "maxResults": 500,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/kijiji-scraper").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 = {
    "categoryPath": "b-cars-trucks/canada/c174l0",
    "query": "",
    "minPrice": 0,
    "maxPrice": 0,
    "maxResults": 500,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/kijiji-scraper").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 '{
  "categoryPath": "b-cars-trucks/canada/c174l0",
  "query": "",
  "minPrice": 0,
  "maxPrice": 0,
  "maxResults": 500,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call logiover/kijiji-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/ebDzUPyMLaVqNkBIm/builds/QqCOfRA26iYtaEy7q/openapi.json
