Skip to content
Back to skills

kleinanzeigen-reader

ASecurity

Read, scrape, and analyze ANY listing from kleinanzeigen.de — cars, electronics, furniture, real estate, clothing, or any other category. Use this skill whenever the user shares a kleinanzeigen.de URL, asks to "check this listing", wants to compare multiple ads, needs to detect if a seller is a dealer or private person, wants to find duplicate listings, or asks "is this a good deal?" for any German classifieds ad. Works without Playwright or external APIs.

  • 4 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added June 2, 2026
developmentpythongobashapi

Works with

  • api

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned June 2, 2026

npx -y skills add its-me-prash/kleinanzeigen-reader --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of kleinanzeigen-reader?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for kleinanzeigen-reader
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/its-me-prash-kleinanzeigen-reader/badge)](https://www.skillsdirectory.com/skills/its-me-prash-kleinanzeigen-reader)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: kleinanzeigen-reader
version: 2.0.0
description: >
  Read, scrape, and analyze ANY listing from kleinanzeigen.de — cars, electronics,
  furniture, real estate, clothing, or any other category. Use this skill whenever
  the user shares a kleinanzeigen.de URL, asks to "check this listing", wants to
  compare multiple ads, needs to detect if a seller is a dealer or private person,
  wants to find duplicate listings, or asks "is this a good deal?" for any German
  classifieds ad. Works without Playwright or external APIs.
---

# Kleinanzeigen Reader — Universal Listing Analyzer

Extracts structured data from any kleinanzeigen.de listing using three built-in
HTML data sources. No browser automation, no paid APIs, no external dependencies.

---

## Quick Start

When a user shares a `kleinanzeigen.de/s-anzeige/...` URL:

1. **Fetch** the page → `scripts/fetch.sh [URL]` or inline curl (Step 1)
2. **Extract** all data → `python3 scripts/extract.py listing.html`
3. **Identify category** → auto-detect from `ad_attributes` or title
4. **Apply category rules** → load the relevant reference file
5. **Output** structured result with flags and recommendation

For multiple URLs → use compare mode (Step 5).

---

## Step 1 — Fetch the Listing

```bash
curl -s -L \
  -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1" \
  -H "Accept-Language: de-DE,de;q=0.9" \
  -H "Referer: https://www.kleinanzeigen.de/" \
  --compressed \
  "[URL]" > /tmp/listing.html
```

**Why iPhone UA:** Kleinanzeigen blocks headless/server requests but allows
mobile Safari — this is a well-documented characteristic of their bot filter.

---

## Step 2 — Three Data Sources (Always Present)

### Source A — Schema.org JSON-LD
SEO requirement. Always in `<script type="application/ld+json">`.
Contains: title, description, asking price, main image URL.

### Source B — `ad_attributes` GTM String
All structured attributes packed into a pipe-separated string for Google Tag Manager:
```
km:95000|aussenfarbe:schwarz|schaden:t|power:150|tuevdate:2026-08|...
```
→ See `references/ad-attributes-fields.md` for complete field list.

### Source C — DFP Bidder Block
A second JS block with cleaner values for key fields:
`ExactPreis`, `Kilometerstand`, `Erstzulassung`, `HU_bis`, `Marke`, `Getriebe`

### Source D — Seller Type
- `"li":"0"` in GTM = **Privater Anbieter**
- `"li":"1"` in GTM = **Gewerblicher Händler**
- Confirmed by text badge: "Privater Nutzer" vs "Gewerblicher Anbieter"
- `"lsc":["0"]` = additional private/commercial signal

---

## Step 3 — Dealer Detection

Extract and evaluate **four dealer signals** — combine for confidence score:

| Signal | Where | Private | Dealer |
|---|---|---|---|
| `li` field | GTM JS | `"0"` | `"1"` |
| `lsc` field | GTM JS | `["0"]` | `["1"]` or higher |
| Badge text | HTML | "Privater Nutzer" | "Gewerblicher Anbieter" / "Händler" |
| Ad volume | Other ads URL | Low | High (fetch counter if needed) |

**Output format:**
```
Verkäufertyp: ✅ Privat  /  ⚠️ Gewerblich (Händler)
```

**Why this matters:**
- Dealers must provide 2-year statutory warranty (§ 475 BGB) — negotiating room is different
- Private sellers can exclude warranty entirely
- Dealer listings often have inflated prices vs. identical private listings
- Some "private" listings are actually undeclared commercial sellers (grey zone)

**Undeclared dealer heuristics** (flag if 2+ match):
- Title uses commercial language ("sofort verfügbar", "Händler", "Bestand")  
- Multiple identical or very similar listings from same seller
- Price is at or above market rate with no personal story in description
- Description is structured/template-like (no typos, no personal details)
- Generic stock photos (no personal garage / street background)

---

## Step 4 — Universal Category System

Auto-detect category from `ad_attributes` fields or listing title, then load
the matching reference file for category-specific analysis.

| Category | Detection | Reference File |
|---|---|---|
| **Fahrzeuge** | `marke`, `km`, `fuel`, `power` present | `references/categories/fahrzeuge.md` |
| **Immobilien** | `zimmer`, `wohnflaeche`, `mietpreis` present | `references/categories/immobilien.md` |
| **Elektronik** | `zustand` + known brands (Apple, Samsung...) | `references/categories/elektronik.md` |
| **Möbel & Haushalt** | No vehicle/immo fields, physical object | `references/categories/moebelhaushalt.md` |
| **Allgemein** | No category match | Apply generic output only |

If category is unclear → use generic output (Step 4b) without loading a reference file.

---

## Step 4a — Category-Specific Flags

### Fahrzeuge (see `references/categories/fahrzeuge.md`)
- `schaden:t` = declared damage → always highlight
- `tuevdate` expired = HU fällig → cost ~€80–150
- KM > 300k = high mileage note
- Motor identification from PS + build year (BMW N47/M47, VW TDI etc.)
- Duplicate detection: same car listed twice at different prices

### Immobilien
- `zimmer` count vs. `wohnflaeche` ratio → abnormal if < 15m² per room
- `kaltmiete` vs. area median (flag if > 30% above)
- Missing fields: no floor plan, no energy certificate mentioned

### Elektronik
- `zustand` field: `neu`, `wie_neu`, `gut`, `akzeptabel`, `defekt`
- `defekt:t` equivalent = listed under "Defekt / Bastlerware"
- Price vs. idealo/Amazon median (mention to check externally)
- Serial number fraud risk for high-value items (MacBooks, iPhones)

### Möbel & Haushalt
- No structural red flags — focus on description quality and seller type
- Note if price > 60% of new price (rarely worth it for furniture)

---

## Step 4b — Universal Output Format

Use this format for **all categories**:

```
## [Title]

**Kategorie:** [detected category]
**Verkäufertyp:** ✅ Privat  /  ⚠️ Gewerblich

| Feld          | Wert                          |
|---------------|-------------------------------|
| Preis         | X.XXX € [VB / Festpreis]      |
| Standort      | [PLZ City]                    |
| Datum         | [listing date]                |
| Zustand       | [if present]                  |
| [cat fields]  | [category-specific rows]      |

**Beschreibung:** [original text]

**⚠️ Flags:**
- [flag 1]
- [flag 2]

**Bilder:** [N] Fotos verfügbar
[image URLs listed]

**Gesamtbewertung:** ★★★☆☆  [short reasoning]
```

---

## Step 5 — Comparison Mode

When 2+ URLs are given, fetch all listings then produce:

```
| Merkmal        | Inserat 1   | Inserat 2   | Inserat 3   |
|----------------|-------------|-------------|-------------|
| Preis          | ...         | ...         | ...         |
| Verkäufertyp   | Privat ✅   | Händler ⚠️  | ...         |
| [cat fields]   | ...         | ...         | ...         |
| Flags          | ...         | ...         | ...         |
| Bewertung      | ★★★☆☆      | ★★☆☆☆      | ...         |
```

**Duplicate detection:** If ≥5 fields match across listings AND location matches
→ flag as probable same item listed twice (common seller tactic to test prices).

---

## Step 6 — Images

Download with:
```bash
curl -s -L \
  -H "Referer: https://www.kleinanzeigen.de/" \
  "[IMAGE_URL]" -o image.jpg
```

URL format: `https://img.kleinanzeigen.de/api/v1/prod-ads/images/[2ch]/[UUID]?rule=X`

| Rule | Size | Use |
|---|---|---|
| `$_57.AUTO` | ~200px thumbnail | Overview |
| `$_59.AUTO` | 720px | Default — good quality |
| `$_2.AUTO` | Full size | Damage inspection |

---

## Limitations

- `kleinanzeigen.de` web URLs only — convert app share links first
- `ezdate` / `tuevdate` = current month if seller left field blank
- Personal data in listing descriptions (phone numbers, names) — do not store or repeat
- Rate limit: add `sleep 1` between requests for batch operations
- For research/personal use only — respect kleinanzeigen.de ToS

---

## Reference Files

- `references/ad-attributes-fields.md` — All GTM field names + values
- `references/categories/fahrzeuge.md` — Vehicle-specific analysis rules
- `references/categories/elektronik.md` — Electronics flags + fraud indicators
- `references/categories/immobilien.md` — Real estate checks
- `references/categories/moebelhaushalt.md` — Furniture/household rules

Files in this skill

  • CLAUDE.md2.4 KB
  • README.de.md4.2 KB
  • README.fr.md4.3 KB
  • SKILL.md8.2 KB
  • claude-skill/SKILL.md6.1 KB
  • github-pull-skill/SKILL.md2.1 KB
  • kl_reader/__init__.py444 B
  • kl_reader/__main__.py81 B
  • kl_reader/analyzer.py4.3 KB
  • kl_reader/cli.py10.7 KB
  • kl_reader/comparator.py1.6 KB
  • kl_reader/extractor.py7.6 KB
  • kl_reader/images.py1.6 KB
  • kl_reader/scraper.py2.4 KB
  • references/ad-attributes-fields.md2.8 KB
  • requirements.txt55 B
  • scripts/compare.py7 KB
  • scripts/extract.py16.4 KB
  • setup.py954 B
  • tests/test_extractor.py5.6 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.