2dehands & 2ememain Scraper (GDPR-safe) avatar

2dehands & 2ememain Scraper (GDPR-safe)

Pricing

from $1.99 / 1,000 results

Go to Apify Store
2dehands & 2ememain Scraper (GDPR-safe)

2dehands & 2ememain Scraper (GDPR-safe)

Scrape 2dehands.be and 2ememain.be listings as clean JSON: prices, descriptions, categories, locations, images and posting dates. GDPR-safe by design: no seller names or other personal data. Splits large searches automatically to fetch every result. Pay per result.

Pricing

from $1.99 / 1,000 results

Rating

0.0

(0)

Developer

Lowland Data

Lowland Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 minutes ago

Last modified

Categories

Share

2dehands & 2ememain Scraper — GDPR-safe listings data

Extract listings from 2dehands.be and 2ememain.be — Belgium's largest second-hand marketplaces — as clean, structured JSON. Prices, descriptions, categories, locations, images and posting dates, ready for price monitoring, market research and data pipelines.

No seller personal data, ever. This scraper is built GDPR-first: seller names, IDs, phone numbers and profile links never appear in the output — not as an option you have to remember to switch off, but by design. The only seller information included is whether the listing comes from a business or a private seller.

What you get

Each listing is one dataset item:

{
"listingId": "m2419606891",
"title": "Jongensfiets Gazelle Esprit zwart",
"description": "Nieuw aangekocht in oktober 2024...",
"priceCents": 40000,
"priceType": "MIN_BID",
"city": "Balen",
"country": "België",
"latitude": 51.166343,
"longitude": 5.189532,
"postedAt": "Vandaag",
"imageUrls": ["//images.2dehands.com/api/v1/..."],
"categoryId": 455,
"url": "https://www.2dehands.be/v/fietsen-en-brommers/...",
"attributes": { "condition": "Zo goed als nieuw", "delivery": "Ophalen" },
"sellerType": "private"
}

Field notes, so you know exactly what you are buying:

  • priceCents is the asking price in euro cents; listings without a price omit it. priceType tells you how to read it: FIXED (asking price) or MIN_BID (minimum bid), plus the marketplace's other kinds when they occur.
  • postedAt is the posting date exactly as the marketplace displays it — a date, or a relative label like Vandaag (today) for recent listings.
  • latitude/longitude are the marketplace's own municipality-level coordinates, not a seller address.
  • description is the snippet the marketplace search returns, not the full listing page text.
  • imageUrls are protocol-relative (//images...); prepend https: to use them.
  • attributes contains the whitelisted set: condition and delivery, when the listing has them.

Use cases

  • Price monitoring — track asking prices for a product or category over time
  • Market research — supply, pricing and location analysis for the Belgian second-hand market
  • Resale arbitrage — find underpriced listings the moment they appear (sort by date)
  • Data feeds — clean, compliance-friendly input for dashboards, ML models and AI agents

Input

FieldDescription
searchQueryFree-text search, e.g. gazelle. Provide this, a category, or both.
domain2dehands.be (Dutch, default) or 2ememain.be (French). Same listings, different language.
categoryIdNumeric category ID to scope the crawl. See below for finding IDs.
priceMinEur / priceMaxEurOnly listings within this price range, in EUR.
sortBydate (newest first, default), price_asc, price_desc, or relevance.
maxItemsStop after this many listings. Default 1,000.

A run needs at least a search query or a category — the marketplace has no "everything" feed, and the actor tells you so up front instead of returning an empty dataset.

Finding a category ID

Every result includes its categoryId. The quickest way to discover IDs is to run a broad search once and read the category IDs off the results you care about, then use them as input for scoped crawls.

Use it from your code

Run the actor and get items straight back with one HTTP call (fine for scoped runs up to ~5 minutes):

curl "https://api.apify.com/v2/acts/lowlanddata~tweedehands-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
-X POST -H "Content-Type: application/json" \
-d '{"searchQuery": "gazelle", "maxItems": 100}'

Node.js:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('lowlanddata/tweedehands-scraper').call({
searchQuery: 'gazelle',
maxItems: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("lowlanddata/tweedehands-scraper").call(
run_input={"searchQuery": "gazelle", "maxItems": 100})
items = client.dataset(run["defaultDatasetId"]).list_items().items

For large split crawls, start the run asynchronously and fetch the dataset when the finished-run webhook fires. Schedules (e.g. a daily price snapshot), webhooks and the Make/Zapier/n8n integrations all work out of the box — this is a standard Apify actor.

Beyond the 5,000-result window

The marketplace API returns at most 5,000 results per query. This scraper automatically splits large queries by category and price band and deduplicates across the shards, so broad crawls are not silently truncated at 5,000 items — a common limitation of similar scrapers. A 60,000-result crawl has been verified end-to-end.

Pricing

Pay per result: you pay for listings actually delivered to your dataset, plus your own platform usage — no subscription, no charge for empty or failed runs. Platform usage is small: a scoped few-hundred-item run costs well under a cent on top of the per-result fee; very large split crawls add roughly $0.10 per 1,000 items. Datacenter proxies are sufficient — no residential proxy surcharge needed.

Free-plan runs are limited to a sample of 25 items, enough to evaluate the output format against your real query.

Compliance

The output contains only public, non-personal commercial data: listing content, prices, categories and municipality-level locations. Seller-identifying fields are removed structurally before anything reaches your dataset — the mapper whitelists fields in, it does not filter fields out, so new marketplace fields can never leak through. Requests are rate-limited to keep load on the marketplace negligible.

Troubleshooting

The actor fails fast with the reason in the run's status message:

  • "Provide a search query, a category, or both." — the input was empty; fill in searchQuery and/or categoryId.
  • "priceMinEur must not be higher than priceMaxEur." — inverted price range.
  • Unknown category errors — the marketplace rejected the categoryId; re-check it against a recent result.
  • Fewer items than requested on a free plan — the 25-item free sample cap; run on a paid Apify plan for full results.

Support

Found an issue or missing a field you need? Open an issue on the actor's Issues tab — reports get fixed, this actor is actively maintained.