Skip to main content

Autolina Scraper

CI PyPI License: MIT Python 3.11+

Unofficial, independently developed project — not affiliated with, endorsed by, or sponsored by autolina.ch ag. "autolina" is a trademark of its respective owner.

Fetches every listing for a given make/model from autolina.ch — for free, no API key, no paid scraping service. It's designed as a drop-in, API-compatible sibling to autoscout24-scraper: same scrape() signature, same ScrapeResult shape, same CLI flags — swap the import and point it at a different Swiss car marketplace.

autolina.ch has no public JSON API the way AutoScout24 does — it's a single server-rendered Angular app — so this scraper parses the same server-rendered HTML, using a small set of generic, resilient selectors rather than brittle hardcoded field positions (see "How the data is obtained"). By default it does a two-phase scrape: search to collect every matching listing id, then visit each one individually for the full record (VIN, energy data, standard/optional equipment, dealer contact info, images, ...). Every spec row and equipment item the site renders is kept — nested objects are flattened into parent_child CSV columns, lists are joined into semicolon-separated cells — nothing is silently dropped. Results are always ordered newest-first.

🤖 Robot-friendly. This project is explicitly intended to be run, read, imported, or adapted by AI agents and bots, same as a human developer — see License. It only ever requests autolina.ch's open, robots.txt-permitted routes and identifies itself honestly; see Compliance for exactly which routes and why.

Setup

Requires pipenv (brew install pipenv).

git clone https://github.com/danyk20/autolina-scraper.git
cd autolina-scraper
pipenv install --dev

Contributing, linting, and testing commands: see CONTRIBUTING.md.

Usage

CLI

pipenv run python -m autolina_scraper.cli --make VW --model Tiguan

Prints progress, then writes vw_tiguan.csv and vw_tiguan.json in the current directory. Installed via pip install instead? The same command is autolina-scraper --make VW --model Tiguan.

Flag Description
--version Print the installed version and exit
--make Make name or slug, e.g. VW or vw (required)
--model Model name or slug, e.g. Tiguan or tiguan (required)
--domain Country domain (default ch) — autolina.ch only exists for ch
--category Vehicle category — only car is supported (no motorcycles)
--out Output file base name, without extension. Defaults to <make>_<model>
--no-detail Skip per-listing detail visits; keep only summary fields (faster, fewer fields)
--delay Seconds between requests (default 1.0) — raise this if you get rate-limited
--price-from / --price-to Filter by price in CHF (inclusive, either end optional)
--mileage-from / --mileage-to Filter by mileage in km (inclusive, either end optional)
--year-from / --year-to Filter by first-registration year (inclusive, either end optional)
--max-results Cap the number of listings collected/detail-visited (default: unlimited)
-v / --verbose Also show debug-level detail (mutually exclusive with -q)
-q / --quiet Suppress progress output; only warnings/errors (mutually exclusive with -v)

Filters combine with AND and are applied server-side (confirmed against the live site), so they also cut down how many listings get visited in the detail phase. A mistyped make/model prints a clean error (plus, for an unknown model, the list of valid models) instead of crashing.

# Fast mode: search results only, skip per-listing detail
pipenv run autolina-scraper --make VW --model Tiguan --no-detail

# 2018 or newer, under CHF 30'000, under 60'000 km
pipenv run autolina-scraper --make VW --model Tiguan --price-to 30000 --year-from 2018 --mileage-to 60000

# A broad, unfiltered search can run into the hundreds of listings — each an
# extra request in the detail phase. Cap it:
pipenv run autolina-scraper --make VW --model Tiguan --max-results 50

As a library

pip install autolina-scraper
from autolina_scraper import scrape

result = scrape("VW", "Tiguan", price_to=30000, year_from=2018)

for row in result.rows:          # list[dict], CSV-ready
    print(row["price"], row["mileage"], row["url"])

result.to_csv("vw_tiguan.csv")   # optional — no files are written unless you ask

A plain, unfiltered search can easily run into the hundreds of listings — max_results caps how many get a (comparatively expensive) detail-page visit, without affecting total_elements (the site's true full count):

result = scrape("VW", "Tiguan", max_results=50)

Need more control over which listings are worth a detail visit — cheapest first, only what changed since your last run, whatever suits your use case? Use the search and detail phases separately instead of the single scrape() call, mirroring the AutoScout24 reference's own search_listings()/visit_all_listings() split:

from autolina_scraper import search_listings, visit_all_listings
from autolina_scraper.http import new_session

session = new_session()
total, listings = search_listings(session, "vw", "tiguan", max_results=200)

listings.sort(key=lambda listing: listing["price"] or 0)
cheapest_ten = listings[:10]

enriched = visit_all_listings(session, cheapest_ten)  # only 10 detail requests

Full scrape() signature, the ScrapeResult return type, the complete field schema, and how this differs from the AutoScout24 reference: docs/REFERENCE.md.

Testing

pipenv run pytest                    # unit tests (fast, no network), coverage gate enforced
pipenv run pytest -m e2e --no-cov    # end-to-end tests against the real live site

Unit tests mock all HTTP (via responses) against real saved HTML fixtures — no network access, no live-site dependency. E2E tests target a small-inventory make/model to confirm the scraper still works against the live site.

Contributing

See CONTRIBUTING.md for dev setup, pre-PR checks, and what to do if autolina.ch changes its markup and a test starts failing.

Be a reasonable citizen: the default request delay is intentional — this project only works because it sticks to autolina.ch's own open, robots.txt-permitted routes. Don't remove the delay, don't crank up concurrency, and never point this at the site's Cloudflare-protected internal routes.

License

Released under the MIT License — you can use, copy, modify, merge, publish, distribute, and sell copies of this code, for free, for any purpose, commercial or not, as long as the license text stays attached. No warranty.

AI agents, LLM-based coding assistants, and other bots are explicitly welcome to use this project — to run the scraper, read and parse its output, import scrape() into another project, or read and adapt its source — under exactly the same terms as a human, with no additional restriction and no need to ask permission. That's why docs/REFERENCE.md documents the full function signature, return type, and data schema: so a bot can integrate correctly without a human in the loop.

This license does not grant any rights to autolina.ch's own data or terms of service — this project only automates requests to routes autolina.ch's own robots.txt permits a normally-identified crawler to fetch; what you do with the results is between you and them.

Metadata

Release files for autolina-scraper 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for autolina-scraper 0.3.1
File Size Uploaded
autolina_scraper-0.3.1.tar.gz 264.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for autolina-scraper 0.3.1
File Interpreter ABI Platform
autolina_scraper-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 291.3 kB

Release files / autolina_scraper-0.3.1.tar.gz

Download URL autolina_scraper-0.3.1.tar.gz
Size 264.1 kB
Tags Source
SHA-256 checksum
How to use checksums
98dc43cc442764aa5c0070563c5580f7c9b6b842fccd35701e3b0490fa2368c0
BLAKE2b-256 checksum
How to use checksums
e39ba5ac89b2a4bd89c2e9e49eab66a687ba19d58bed6e129561d4c8d97daf83
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.

Transparency log

Release files / autolina_scraper-0.3.1-py3-none-any.whl

Download URL autolina_scraper-0.3.1-py3-none-any.whl
Size 27.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e9d7913269ede0bc4a483b005090c6e547743d0b6c73524a714f960830254f4b
BLAKE2b-256 checksum
How to use checksums
26547716a4e9ddc14818f263156eac58bde5a49ac7d37cea71a131d2922286e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 21, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page