L logiover
business · Jul 9, 2026 · 7 min read

How to Scrape Casa.it Italy Real Estate Data in 2026

Extract Italian property listings from Casa.it — prices, EUR/m², GPS, energy class and agency phone numbers — past DataDome, with no API key or browser.

Casa.it is one of Italy’s largest residential-property portals, with hundreds of thousands of active vendita (sale) and affitto (rent) listings across every region. There is no open public API, and if you point a plain curl request at a search page you’ll hit a DataDome challenge before you ever see a listing. This guide covers what Casa.it actually exposes, how its data is embedded in the page, and how to pull clean, structured Italian real-estate records — price, price per square meter, GPS, energy class and agency contact — without maintaining a browser fleet.

What’s worth extracting

Casa.it packs a dense record behind every listing card. Once you parse the page’s embedded state, each property yields roughly 60+ fields. The ones that matter for most pipelines group into five clusters:

  • Pricingprice (asking price for sales), priceLabel (the formatted string as shown, e.g. € 395.000), priceCurrency (EUR), pricePerSqm (computed EUR/m²), monthlyRent for rentals, mortgage (estimated monthly payment), and hasPriceRange when the figure is a band rather than a fixed number.
  • Property specareaSqm, rooms (locali), bathrooms (bagni), parkings, floor, energyClass (A4–G), availability, plus flags like isAuction and isNewDevelopment.
  • Location — a full Italian address breakdown: street, block, district, city, province, region, a composed fullAddress, and latitude/longitude for mapping.
  • Agency / sellerpublisherName, publisherId, publisherType (Agency vs. private), publisherPhone, publisherWebsite, publisherUrl (profile on Casa.it), and the agency’s own postal address (publisherStreet, publisherTown, publisherProvince, publisherPostcode).
  • MediamainImageUrl, an imageUrls array at your chosen resolution, imageCount, floorplanCount, and the hasVideo / has360 / has3dTour flags.

For a EUR/m² market-mapping job you need price, area and location. For lead generation, the publisherPhone and publisherType fields are the payload.

How Casa.it serves its data

The actor doesn’t render pages or walk the DOM. Casa.it is a server-rendered React app that ships its full page state in an embedded __INITIAL_STATE__ JSON blob inside the HTML. The listing array — prices, coordinates, agency data and all — is already in that payload before any JavaScript runs. The actor fetches the search HTML over HTTP, extracts __INITIAL_STATE__, and reads the structured objects directly. No headless Chrome, no GraphQL token, no site API key.

Search targeting works through URL location slugs. Casa.it URLs follow a predictable shape:

https://www.casa.it/vendita/residenziale/roma/     → sale in Rome
https://www.casa.it/affitto/residenziale/milano/   → rent in Milan

The slug is the segment after /vendita/residenziale/ (sale) or /affitto/residenziale/ (rent). You can pass a city (roma), a province, or a deeper zone segment. Each slug you supply becomes its own scraping task, so you can benchmark several cities in one run.

A realistic input — Rome and Milan apartments for sale, filtered by price, area and rooms, largest budget first:

{
  "locationSlugs": ["roma", "milano"],
  "transaction": "sale",
  "propertyType": "apartment",
  "priceMin": 150000,
  "priceMax": 600000,
  "areaMin": 50,
  "areaMax": 120,
  "roomsMin": 2,
  "bathroomsMin": 1,
  "sort": "price_asc",
  "maxListings": 500,
  "maxPagesPerTask": 10,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "IT" }
}

The propertyType filter accepts the full residential taxonomy: apartment, penthouse, villa, terraced_house, detached_house, farmhouse, loft, studio, and the two_room / three_room / four_room flat sizes, or all. sort supports relevance, latest, and price/area ascending or descending.

Run the Casa.it Italy Real Estate Scraper on Apify — one run returns thousands of Italian listings with price, EUR/m², full address, GPS and agency phone. No API key, no login. Export to JSON, CSV, Excel or XML.

The access reality: DataDome

The real friction on Casa.it isn’t the data format — it’s the bot wall. Casa.it is fronted by DataDome, which fingerprints requests at multiple layers and treats datacenter ASNs as guilty by default. A naive stack (a Python HTTP client plus a User-Agent string plus a free proxy) fails on the first request.

What works in production:

  • Residential proxy, country IT. Datacenter proxies are blocked. The actor defaults to Apify residential proxy with apifyProxyCountry: "IT", which presents Italian residential IPs.
  • IP rotation on every block. When a request is challenged, the actor rotates to a fresh IP and retries. DataDome earns a healthy retry budget — the README recommends maxRetries of 6–10.
  • Realistic pacing. Keep requestDelay at or above 600 ms between page requests. Hammering the same session at 50 requests a second is the fastest way to get the whole run flagged.
  • User-agent rotation paired with a realistic browser fingerprint so the request headers look like a real Italian visitor’s browser.

This is the exact class of engineering that eats a week if you build it yourself, and then needs re-tuning every time DataDome ships an update. Casa.it returns roughly 20–25 listings per page, so pagination depth (maxPagesPerTask) is what gets you into deep inventory once your proxy and retry logic hold.

Example output

A single sale listing after parsing, trimmed to the load-bearing fields:

{
  "adId": "82715349",
  "detailUrl": "https://www.casa.it/immobili/82715349.html",
  "title": "Trilocale via Nazionale, Centro Storico, Roma",
  "transactionType": "sale",
  "propertyType": "appartamento",
  "price": "395000",
  "priceCurrency": "EUR",
  "pricePerSqm": "4938",
  "areaSqm": "80",
  "rooms": "3",
  "bathrooms": "2",
  "energyClass": "C",
  "city": "Roma",
  "province": "Roma",
  "region": "Lazio",
  "latitude": "41.8987",
  "longitude": "12.4901",
  "publisherName": "Roma Immobiliare Srl",
  "publisherPhone": "+39 06 1234567",
  "publisherWebsite": "https://www.romaimmobiliare.it",
  "scrapedAt": "2026-07-06T09:15:00.000Z"
}

Every value ships as a string, including numeric fields — cast price, pricePerSqm and areaSqm in your ingestion step.

Who uses Casa.it data

  • Market research — build EUR/m² heatmaps by region, province, city and district across the Italian market. The pricePerSqm field is already computed per listing.
  • Investment and rental-yield screening — scrape sale and rent listings for the same area, then compare monthlyRent against price and pricePerSqm to compute gross rental yield per neighbourhood.
  • Agency lead generation — set sellerType: private to find direct-owner (privato) listings, or cluster agency listings by publisherId and pull publisherPhone and publisherWebsite for outreach lists.
  • Price tracking — re-run on a schedule and diff against prior datasets on adId to catch price cuts and new inventory.
  • Energy-efficiency analysis — filter and aggregate by energyClass (A4–G) to study the Italian housing stock and the green-retrofit segment.
  • Cross-city benchmarking — pass Roma, Milano, Napoli and Torino as slugs in one run and compare like-for-like.

Build it yourself vs. use the managed actor

The math tilts hard toward managed once DataDome is in the picture:

  • Build from scratch — 2–5 days for a working extractor, plus a residential proxy pool at roughly $300–500/month for anything respectable, plus recurring maintenance every time DataDome rotates its challenge. You also carry the __INITIAL_STATE__ parsing when Casa.it changes its state shape.
  • Managed actor — start in minutes, pay per result. The pricing model is pay-per-result: you’re charged for the listings you extract, with no Casa.it API fees and no monthly floor. Cap any run with maxListings and maxPagesPerTask to stay inside budget. At a fraction of a cent per row, a 5,000-listing sweep lands in the low single digits of dollars including proxy bandwidth.

The recurring cost that matters most is engineering time. Hours spent debugging DataDome challenges are hours not spent on your product.

Common pitfalls

Specific gotchas for a Casa.it pipeline:

  • Everything is a string. price, pricePerSqm, areaSqm, latitude, longitude, imageCount — all ship as strings. Coerce types before you compute yields or plot coordinates.
  • price vs. monthlyRent is transaction-dependent. For sales, the asking price is in price and monthlyRent is null; for rentals, it’s the reverse. pricePerSqm is computed from whichever applies, so it’s populated in both cases.
  • Slug scoping controls volume. A bare city slug returns everything in that comune; a deeper zone segment narrows it. Pick the granularity that matches your analysis or you’ll over- or under-collect.
  • hasPriceRange matters for auctions and new builds. When it’s true, treat price as the lower bound of a range, not a fixed quote — relevant when isAuction or isNewDevelopment is set.
  • Image CDN URLs and resolution. imageUrls come at the resolution you set via imageSize (up to 1280×960). Store the URLs but expect image paths to rotate over time; don’t treat them as permanent.
  • GDPR on agency contacts. publisherPhone and the agency address are publicly listed business contact data, but you’re responsible for handling them in line with Casa.it’s terms and the GDPR when you use them for outreach.

Scheduling and keeping the data fresh

Property inventory turns over constantly — listings appear, prices drop, sold units disappear. A one-time scrape is a snapshot; the value in real-estate data is in the diff over time. Schedule the actor on Apify to re-run daily or weekly against the same set of locationSlugs, then diff each run against the prior dataset on the stable adId to detect three things: new listings (an adId you haven’t seen), price changes (same adId, different price or pricePerSqm), and removals (an adId that dropped out). Push results to Google Sheets for a lightweight dashboard, or wire the run into Make, n8n or Zapier to trigger price-drop alerts and CRM syncs. Combining several location slugs and property types across scheduled runs is how you build a nationwide Italian dataset that stays current without manual re-scraping.

Wrapping up

If you need a one-off dataset, building your own __INITIAL_STATE__ parser is a decent exercise — until DataDome forces you to solve the proxy-and-retry problem too. If you need a refreshed Italian property feed with EUR/m², GPS and agency leads on every row, run a managed actor where the DataDome handling is already solved and kept green.

Open the Casa.it Scraper on Apify — DataDome-aware, residential-proxy backed, 60+ fields per listing including agency phone and website. No API key. Pay per row. Start on Apify’s free monthly credit.

Related guides