DEV Community

Ben
Ben

Posted on

How to Scrape Real Estate Listings from Kleinanzeigen (Germany) — Python + No-Code

Kleinanzeigen (formerly eBay Kleinanzeigen) is Germany's largest classifieds site,
and its Immobilien section is one of the richest sources of private-landlord
rental and sale listings anywhere in the DACH region — the kind of inventory that
never makes it onto the big paid portals. If you're building a rental-market
dashboard, a relocation tool, or just hunting for underpriced flats, this is where
the data is.

The problem: Kleinanzeigen renders server-side German HTML, blocks datacenter IPs,
and hides the structured attributes (Zimmer, Wohnfläche, Kaltmiete) inside the
detail page. Here's how to get clean data out of it.

Why Kleinanzeigen for real estate?

  • Private landlords — many listings are direct from owners, often below market and absent from Immowelt/ImmoScout.
  • Hyper-local — search any PLZ or city with a radius, down to the district.
  • Structured fields — rooms, living space, cold/warm rent, deposit, availability date and more, once you parse the detail page.

The hard part: location IDs and German attributes

Two things trip up a naive scraper:

  1. Location resolution. Kleinanzeigen doesn't search by city name directly — it uses internal location IDs (e.g. Berlin → l3331). You resolve them through its autocomplete endpoint:
import httpx

q = "münchen"
r = httpx.get("https://www.kleinanzeigen.de/s-ort-empfehlungen.json",
              params={"query": q}, timeout=15)
# -> {"_6411": "München", ...}  the digits after the underscore are the location id
print(r.json())
Enter fullscreen mode Exit fullscreen mode
  1. Attribute parsing. On the detail page each attribute is a label/value pair without a clean class on the label, so you read the value node and strip it back out of the row text:
from bs4 import BeautifulSoup

soup = BeautifulSoup(html, "lxml")
attrs = {}
for li in soup.select(".addetailslist--detail"):
    val = li.select_one(".addetailslist--detail--value")
    if not val:
        continue
    value = val.get_text(" ", strip=True)
    label = li.get_text(" ", strip=True).replace(value, "", 1).strip()
    attrs[label] = value
# attrs -> {"Wohnfläche": "72 m²", "Zimmer": "3", "Kaltmiete": "1.150 €", ...}
Enter fullscreen mode Exit fullscreen mode

You also need a residential DE proxy — datacenter IPs get a soft block fast.

The catch: scale and upkeep

One listing is easy. A useful dataset needs paging through hundreds of results,
fetching every detail page politely, normalizing German fields into clean keys
(rooms, living_space_sqm, cold_rent_eur), handling umlauts in city slugs, and
rotating residential IPs — then staying alive as the markup shifts. That's days of
maintenance.

The no-code option

The Kleinanzeigen Immobilien Scraper
on Apify does all of it: enter a city or PLZ (names auto-resolve to the right
location ID) and an optional price/room filter, click Run, and get clean rows.

{
  "locationCode": "münchen",
  "radiusKm": 20,
  "maxResults": 200
}
Enter fullscreen mode Exit fullscreen mode

Output is one tidy row per listing — title, rooms, living space, cold/warm rent,
deposit, address, PLZ, images and the listing URL — ready for a spreadsheet, a
database, or an LLM. Residential DE proxies and attribute parsing are built in.

Common use cases

  • Rental-market analysis — track asking rents by district and room count over time.
  • Deal-hunting — surface underpriced private-landlord flats the moment they post.
  • Relocation & proptech apps — power search with structured German listings.
  • Lead generation — reach private landlords directly.

FAQ

Do I need an API key? No — a residential DE proxy is used automatically.

Can I search by city name? Yes — city names auto-resolve to Kleinanzeigen's
internal location IDs; you can also pass a PLZ or paste a full search URL.

Is this legal? You're reading publicly available listing data. Use it responsibly
and within applicable laws and Kleinanzeigen's terms.


Building something with German property data? The Kleinanzeigen Immobilien Scraper handles the scraping so you can focus on the product.

Top comments (0)