DEV Community

Devil Scrapes
Devil Scrapes

Posted on

How to Scrape Autovit.ro Car Listings (Romania) to JSON/CSV

Quick answer: Autovit.ro publishes no public API, so the only way to get structured used-car data is to scrape the public listings. The Autovit Romania Car Scraper on Apify handles browser fingerprint rotation, residential proxy session rotation, and retry logic for you, returning clean typed rows at $2.05 per 1,000 results ($0.05 actor-start + $0.002 per result).


Romania's used-car market runs on autovit.ro. The site is part of the Adevinta/OLX group β€” the same engine that powers OTOMOTO in Poland and Standvirtual in Portugal β€” and it moves serious volume: tens of thousands of listings at any moment, priced in both EUR and RON. If you want to track asking prices, monitor dealer inventory, or build an arbitrage pipeline across the Romanian market, you need that data in a format your code can actually work with.

The problem is that autovit.ro guards its listings behind DataDome, a commercial anti-bot stack that blocks naive HTTP clients almost immediately. Getting past it requires rotating real browser TLS fingerprints, using residential exit IPs, and backing off gracefully when the target pushes back. That's before you even think about pagination.

This guide walks you through exactly how to pull autovit.ro data programmatically, using the Autovit Romania Car Scraper β€” a managed Apify Actor that does the infrastructure work so you can focus on the data.


Does Autovit.ro Have an API? πŸ”Ž

No. Autovit.ro offers no developer API, no data export, and no structured feed. The listing data lives in HTML pages and in embedded JSON-LD payloads β€” both behind DataDome protection. There is also an internal API the site's Next.js frontend calls, but it requires authenticated sessions and rotates its challenge parameters regularly, which means any direct client you build against it breaks without warning.

The practical path is a managed scraper that stays current with the site's anti-bot countermeasures, so your pipeline keeps running when the site updates its defences.


What Data You Can Extract

Each listing on autovit.ro carries a rich spec sheet. The Actor surfaces every field that appears consistently across listings:

Field Description
listing_id Autovit advert ID
listing_url Absolute URL to the listing
title Make + model + version headline
make Manufacturer (e.g. BMW, Dacia, Volkswagen)
model Model name (e.g. Logan, Range Rover Sport)
version Trim / engine spec line
year Production year (Anul producΘ›iei)
price Integer price in listing currency
currency EUR or RON
mileage_km Odometer in kilometres
fuel_type Benzina / Diesel / Hibrid / Electric
gearbox Manuala / Automata (detail page)
transmission Drivetrain, e.g. 4x4 (automat) (detail page)
engine_power_hp Power in horsepower (CP)
engine_size_cc Displacement in cc
body_type SUV / Berlina / Break, etc. (detail page)
color Exterior colour in Romanian (detail page)
location City
region Romanian county / judet
seller_type private or dealer
seller_name Dealer name when present
photo_urls List of photo URLs
description Full Romanian listing text (detail page)
posted_date ISO timestamp of listing creation
scraped_at ISO timestamp of scrape

Fields marked "detail page" are populated only when enrichDetails is enabled. Price, make/model, year, mileage, fuel, power, and seller all come from the search payload β€” you can skip enrichment to halve requests if those are enough.


A Realistic Output Row

Here is what a single result looks like as JSON, using the exact field names from the Actor's Pydantic ResultRow model:

{
  "listing_id": "7058024533",
  "listing_url": "https://www.autovit.ro/autoturisme/anunt/land-rover-range-rover-sport-ID7HEKBn.html",
  "title": "Land Rover Range Rover Sport 4.4 V8 P635 MHEV SV Black",
  "make": "Land Rover",
  "model": "Range Rover Sport",
  "version": "4.4 V8 P635 MHEV SV Black",
  "year": 2026,
  "price": 187737,
  "currency": "EUR",
  "mileage_km": 1,
  "fuel_type": "Benzina",
  "gearbox": "Automata",
  "transmission": "4x4 (automat)",
  "engine_power_hp": 635,
  "engine_size_cc": 4395,
  "body_type": "SUV",
  "color": "Negru",
  "location": "Pitesti",
  "region": "Arges",
  "seller_type": "dealer",
  "seller_name": "BRIT Motor AG - RANGE ROVER | DEFENDER | DISCOVERY",
  "photo_urls": ["https://ireland.apollo.olxcdn.com/v1/files/.../image"],
  "description": "Range Rover Sport 4.4 V8 635 CP AWD Auto MHEV SV Black ...",
  "posted_date": "2026-06-01T17:30:53Z",
  "scraped_at": "2026-06-02T00:00:00+00:00"
}
Enter fullscreen mode Exit fullscreen mode

Notice currency can be either EUR or RON β€” autovit.ro allows sellers to list in both, and the Actor reads each listing's own currency code rather than assuming one.


How We Handle the Blocks

Autovit.ro is fronted by DataDome. A plain requests.get() call gets a challenge page almost immediately. Here is what the Actor does so you don't have to:

  • Browser fingerprint rotation. We use curl-cffi to impersonate real Chrome, Firefox, and Safari TLS handshakes β€” the full ClientHello, ALPN extension order, and HTTP/2 SETTINGS frame. The target sees a real browser, not Python.
  • Residential proxy rotation via Apify Proxy. On every block signal we request a fresh session_id and a new residential exit IP. Datacenter IPs are a fast path to a ban on DataDome targets.
  • Exponential backoff with Retry-After. We retry on 408, 429, and 5xx β€” up to five attempts per page, doubling the wait each time and honouring the server's own Retry-After header.
  • Rate-limit-aware pacing. When the target pushes back, we slow down rather than hammering until banned.
  • Loud failure, never silent. If we hit a hard ban, the Actor exits non-zero with a clear status message. You never get an empty dataset with a green status.

Running It with Python 🐍

Install the Apify client and run the Actor programmatically:

from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("DevilScrapes/autovit-romania-cars").call(
    run_input={
        "searchUrl": "https://www.autovit.ro/autoturisme/bmw",
        "maxResults": 100,
        "enrichDetails": True,
        "proxyConfiguration": {
            "useApifyProxy": True,
            "apifyProxyGroups": ["RESIDENTIAL"]
        }
    }
)

items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(f"Scraped {len(items)} listings")
for item in items[:3]:
    print(item["make"], item["model"], item["year"], item["price"], item["currency"])
Enter fullscreen mode Exit fullscreen mode

The searchUrl is just the autovit.ro results URL with your filters already applied. Open autovit.ro in a browser, set your filters (make, model, price band, mileage range), and copy the URL from the address bar β€” the Actor walks pagination from there.


Use Cases

Used-car price analytics. Build a time series of asking prices for a specific make/model/year combination. Run the Actor daily, push results to a database, and chart the market. Romanian sellers list in both EUR and RON; the currency + price fields let you normalise to whichever you prefer.

Dealer inventory monitoring. Filter by seller_type = dealer and a specific seller_name. Diff successive runs to catch new arrivals and price cuts before competitors do.

Market research. Aggregate fuel_type and gearbox across the full Romanian market to measure EV, hybrid, and automatic transmission adoption over time.

Lead generation. Build a directory of Romanian car dealers from seller_name + location + region. Cross-reference with runs over time to score dealers by listing volume.

Arbitrage and sourcing. Apply tight filters β€” low mileage, specific power band, narrow year range β€” and run daily. Surface underpriced listings the moment they appear.


FAQ ❓

How much does it cost?

Pay-Per-Event pricing: $0.05 for actor-start (one-off per run) plus $0.002 per result row. 1,000 results costs $2.05 total. Every new Apify account gets $5 of free credit β€” no credit card required to try.

Is scraping autovit.ro legal?

Autovit.ro's ToS restricts automated access to the site. You are responsible for ensuring your use complies with applicable law and the site's terms. The Actor scrapes only public listing data that is visible to any unauthenticated browser. We do not bypass authentication, access private user data, or circumvent any paywall.

How often should I run it?

Autovit.ro listing data changes daily. For price-tracking use cases, a daily run is sufficient. For "new listing" alerts you can run every few hours. Apify lets you schedule runs via the Console or the API.

What if listings stop appearing?

DataDome updates its challenge logic periodically. If a run returns fewer results than expected, check the run log β€” the Actor will have logged the HTTP status codes and retry attempts. We ship updates to keep pace with site changes; subscribe to Actor release notes on Apify to get notified.


Get Started

The Actor is live on the Apify Store. Every new Apify account starts with $5 of free credit β€” enough for roughly 2,400 enriched listings at the PPE rates above.

Autovit Romania Car Scraper on Apify Store

Questions or edge cases? Use the Actor's Issues tab on Apify Console. The devil's in the data β€” we read every report.


Built by Devil Scrapes β€” a fleet of opinionated public-data Actors. Honest pricing, real engineering, zero fine print.

Top comments (0)