Self-contained, zero-dependency classifieds scraper for OLX
Duas formas de usar: extensão Chrome (Manifest V3) ou console do navegador.
OLX Scraper is a lightweight, single-file script that extracts every listing from any OLX search results page — including the full ad detail JSON, description text, and structured property specs — without a single external dependency.
Unlike traditional web scrapers that require Node.js, Puppeteer, or Playwright, this script runs directly in your browser console. It works across all OLX subdomains (www.olx.com.br, sp.olx.com.br, rj.olx.com.br, etc.) by leveraging OLX's own internal APIs.
Why this exists: There was no open-source, reliable way to extract structured data from OLX. Existing solutions break on OLX's front-end changes, require heavy tooling, or miss critical fields like
adDate,description, and the completeadDetailpayload. This scraper was built from the ground up by reverse-engineering OLX's client-side data layer.
- Zero dependencies — no npm, no Docker, no Puppeteer. Just copy and paste.
- Class-based API — use
OlxScraper.extract()with optionallimitandminimalmode. - Works on any OLX category — cars, real estate, computers, jobs, anything.
- Full data extraction — captures title, price, URL, seller, location, image, plus the complete
adDetailJSON object. - Minimal mode — get only the essentials: seller, location, date, title, URL, and description.
- Correct adDate — OLX serializes dates incorrectly; this scraper fixes the epoch offset using the accurate timestamp from
dataLayer[0].page.detail.adDate. - Description parsing — extracts descriptions from the schema.org
application/ld+jsonblock. - Structured specs — extracts the
adPropertiesarray, giving you every labeled attribute OLX stores for a listing. - Batch processing — fetches detail pages 5 at a time to avoid overwhelming the browser.
- Cross-subdomain — works seamlessly across all regional OLX subdomains thanks to OLX's permissive CORS policy.
- Human-readable output — prints a formatted JSON array to the console, ready for copy-paste or further processing.
Também disponível como uma extensão Chrome moderna com interface gráfica.
- Clone o repositório ou baixe os arquivos
- Abra
chrome://extensionsno Chrome - Ative Modo do desenvolvedor (canto superior direito)
- Clique Carregar sem compactação e selecione a pasta do projeto
- O ícone da extensão aparecerá na barra de ferramentas
- Navegue até qualquer página de busca do OLX (ex.: carros usados)
- Clique no ícone da extensão na barra de ferramentas
- Ajuste as opções (páginas, limite, modo mínimo, etc.)
- Clique Extrair — a barra de progresso mostra o andamento
- Ao finalizar, clique Download JSON para salvar o resultado
A extensão não substitui o uso via console. O script
olx-scraper.jsoriginal continua funcionando para colar diretamente no console.
- Open your browser and navigate to any OLX search results page (e.g., computers in São Paulo).
- Open the developer console:
- Chrome:
Ctrl + Shift + J(Windows/Linux) orCmd + Option + J(macOS) - Firefox:
Ctrl + Shift + K(Windows/Linux) orCmd + Option + K(macOS)
- Chrome:
- Copy the entire script from
olx-scraper.jsand paste it into the console. - Press
Enter.
The script auto-executes and scrapes all visible listings. Once finished, a JSON array is printed to the console.
=== RESULTADO FINAL ===
[
{
"title": "Computador i5-10400f, 16GB RAM, HD 1TB",
"price": "R$ 1.400",
"url": "https://sp.olx.com.br/sao-paulo/computador-i5-10400f-16gb-ram-hd-1tb-sem-placa-de-video-123456789",
"seller": "João Silva",
"location": "São Paulo - SP",
"img": "https://img.olx.com.br/images/...",
"adDetail": { "subject": "Computador i5-10400f...", "price": 1400, ... },
"description": "Computador com processador Intel Core i5-10400F...",
"adProperties": [
{ "label": "Processador", "value": "Intel Core i5-10400F" },
{ "label": "Memória RAM", "value": "16 GB" }
],
"adDate": "2025-10-28 14:30:00"
}
]Tip: To save the output as a file, type
copy(JSON.stringify(results))after the script finishes — this copies the full JSON array to your clipboard.
The script exposes a global OlxScraper class. Call it again anytime with custom options:
// Full output, no limit, 10 pages (default)
OlxScraper.extract();
// Limit to 10 listings total
OlxScraper.extract({ limit: 10 });
// Minimal mode — only the essentials
OlxScraper.extract({ minimal: true });
// Scrape 5 pages starting from page 3
OlxScraper.extract({ pages: 5, offset: 2 });
// Combined
OlxScraper.extract({ pages: 3, limit: 50, minimal: true });| Option | Type | Default | Description |
|---|---|---|---|
limit |
number |
Infinity |
Maximum number of listings to return |
minimal |
boolean |
false |
When true, return only seller, location, adDate, title, url, description |
pages |
number |
10 |
Number of search result pages to scrape |
offset |
number |
0 |
Skip this many pages before starting (0 = start at page 1) |
timeout |
number |
15000 |
Per-request timeout in milliseconds |
batchSize |
number |
5 |
Number of concurrent detail-page fetches |
When minimal: true, each entry contains only these fields:
{
"seller": "João Silva",
"location": "São Paulo - SP",
"adDate": "2025-10-28 14:30:00",
"title": "Computador i5-10400f, 16GB RAM, HD 1TB",
"url": "https://sp.olx.com.br/sao-paulo/computador-i5-10400f-16gb-ram-hd-1tb-sem-placa-de-video-123456789",
"description": "Computador com processador Intel Core i5-10400F..."
}Use minimal mode when you only need the core listing data — perfect for quick checks, CSV export, or mobile views.
flowchart TD
A(["OLX Grid Page<br/>(results list)"]) --> B["Extract Cards<br/>querySelectorAll section.olx-adcard"]
B --> C["Fetch Detail Pages<br/>XHR GET (batch: 5 at a time)"]
C --> D["Parse HTML Response"]
D --> E["Extract ld+json<br/>script type='application/ld+json'"]
D --> F["Parse dataLayer<br/>balanceJSON + window.dataLayer"]
E --> G["description<br/>(schema.org Product)"]
F --> H["adDetail + adProperties<br/>(page.*)"]
F --> I["Fix adDate<br/>(detail.adDate Unix seconds)"]
G --> J["Assemble Final JSON"]
H --> J
I --> J
J --> K["Output<br/>[{title, price, url, seller,<br/>location, img, adDetail,<br/>description, adProperties, adDate}]"]
style A fill:#e1f5fe,stroke:#0288d1
style K fill:#e8f5e9,stroke:#388e3c
style C fill:#fff3e0,stroke:#f57c00
style J fill:#f3e5f5,stroke:#7b1fa2
sequenceDiagram
participant Console as Browser Console
participant Grid as OLX Grid Page
participant Detail as OLX Detail Page (x N)
participant DL as dataLayer (embedded)
participant LD as ld+json (embedded)
participant Output as Final JSON
Console->>Grid: querySelectorAll('section.olx-adcard')
Grid-->>Console: Array of ad cards
Console->>Console: slice(0, limit) — cap if needed
loop Batch of batchSize
Console->>Detail: XHR GET detail URL
Detail-->>Console: Full HTML
Console->>DL: balanceJSON + JSON.parse
DL-->>Console: adDetail + adProperties
Console->>DL: detail.adDate * 1000
DL-->>Console: Correct Unix timestamp
Console->>LD: regex match ld+json
LD-->>Console: description text
Console->>Console: assembleEntry (minimal filter if true)
Console->>Output: Append to results
end
Console-->>Output: console.log(JSON.stringify(results))
Output-->>Console: Return JSON array
OLX embeds a full dataLayer object in every listing page that contains page.adDetail (the complete ad metadata), page.adProperties (structured specs like processor, RAM, mileage, etc.), and page.detail.adDate (the accurate Unix timestamp). The script:
- Balances braces — uses a character-by-character depth counter to extract the complete JSON array from
window.dataLayer = [...]without a JSON parser. - Parses
ld+json— locates the<script type="application/ld+json">tag and parsesdescriptionfrom the schema.orgProductobject. - Fixes
adDate— replaces the broken serializedadDate(which OLX miscalculates, resulting in dates like1970-01-21) with the correct value frompage.detail.adDate(Unix seconds). - Structures output — assembles everything into a clean JSON array with both grid-level and detail-level data.
| Field | Type | Source | Description |
|---|---|---|---|
title |
string |
Grid card | Listing title |
price |
string |
Grid card | Formatted price (e.g., "R$ 1.400") |
url |
string |
Grid card | Canonical listing URL |
seller |
string |
Grid card | Seller name |
location |
string |
Grid card | City / state |
img |
string |
Grid card | Main image URL |
adDetail |
object |
dataLayer[0].page.adDetail |
Complete listing payload — subject, price (number), category, region, phone, etc. |
description |
string |
ld+json |
Long-form description text |
adProperties |
array |
dataLayer[0].page.adProperties |
Structured spec list [{label, value}] |
adDate |
string |
page.detail.adDate (corrected) |
Publication date YYYY-MM-DD HH:mm:ss |
| Field | Type | Source | Description |
|---|---|---|---|
seller |
string |
Grid card | Seller name |
location |
string |
Grid card | City / state |
adDate |
string |
page.detail.adDate (corrected) |
Publication date YYYY-MM-DD HH:mm:ss |
title |
string |
Grid card | Listing title |
url |
string |
Grid card | Canonical listing URL |
description |
string |
ld+json |
Long-form description text |
The adDetail object is OLX's internal representation of a listing and may contain (depending on category):
subject — listing title
price — numeric price
description — short description (often truncated)
category — category path
region — geographic region
city — city name
adDate — correct publication date (YYYY-MM-DD HH:mm:ss)
phone — contact phone number
images — array of image URLs
lat/lng — coordinates
info_* — category-specific fields (info_computer_processor, info_car_mileage, etc.)
Since the script dynamically extracts the entire adDetail object, it captures every field OLX sends — even ones not documented here.
- Price monitoring — track price changes on specific categories or search terms.
- Market research — aggregate listing data for supply/demand analysis.
- Inventory backup — save your own listings' data for offline records.
- Data portability — extract your data from OLX in a structured, machine-readable format.
- Academic research — study classifieds market trends in Brazil and other OLX markets.
This script has been tested end-to-end on live OLX listings covering multiple categories and regional subdomains. Every major data field (title, price, description, adDetail, adProperties, adDate) has been verified against actual page content.
- Single-session — the script scrapes multiple grid pages in sequence but runs from a single browser tab. You do not need to manually navigate between pages.
- JavaScript required — OLX is a single-page application; the script requires a browser environment with JavaScript enabled.
- Rate limiting — OLX may throttle or block excessive requests. The 5-at-a-time batch processing helps, but use responsibly.
- Terms of Service — review OLX's ToS before performing large-scale scraping. This tool is intended for personal, non-commercial use.
Q: Will this work for non-Brazilian OLX sites?
A: Yes! OLX operates in dozens of countries (India, Portugal, Poland, etc.). The script targets OLX's core data layer, which is consistent across all regional instances.
Q: Can I export to CSV or Excel?
A: After the script runs, use console.table(results) for a tabular view, or pipe the JSON through a converter like jq or an online CSV transformer. For minimal mode, run OlxScraper.extract({ minimal: true }) for a cleaner dataset.
Q: Does it work on mobile?
A: The script is designed for desktop browsers. Mobile browser consoles are limited, but it may work with a mobile bookmarklet.
Q: Why does adDate show 1970 without the fix?
A: OLX serializes adDate in adDetail using a wrong epoch multiplier. The script corrects this by reading the accurate Unix-second timestamp from dataLayer[0].page.detail.adDate.
Q: Can I run it multiple times with different options without re-pasting?
A: Yes! After pasting once, just type OlxScraper.extract({ limit: 5, minimal: true }) in the console. The class stays available.
Contributions are welcome! See CONTRIBUTING.md for guidelines.
Distributed under the MIT License. See LICENSE for more information.
Made with ❤️ in Brazil 🇧🇷