# Wallapop Scraper — Second-Hand Listings & Prices (ES, IT, PT) (`yugenox/wallapop-scraper`) Actor

Scrape Wallapop second-hand listings in Spain, Italy and Portugal by keyword, category and city: title, price, category path, photos, city, posting date, shipping, reserved and promoted flags, car and property specs. Optional condition, brand, size, views and favourites. No login, no seller data.

- **URL**: https://apify.com/yugenox/wallapop-scraper.md
- **Developed by:** [Yugenox Corp](https://apify.com/yugenox) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.30 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Wallapop Scraper: second-hand listings and prices in Spain, Italy and Portugal

Scrape **Wallapop**, the biggest second-hand marketplace in Spain, plus its Italian and Portuguese sites. Search by **keyword, category and city**, with Wallapop's own filters (distance, price, condition, posted date, shipping, sort order). Every listing comes with the **title, price, category path, photos, city and region, posting and edit dates, and the shipping, reserved, refurbished, warranty and promoted flags**. Cars come with **brand, model, year, mileage, fuel, gearbox and horsepower**, and property listings with **sale or rent, type, m², rooms and bathrooms**. Turn on **item details** to add the **condition, brand, size, colour, every car or property attribute, views, favourites and chats**. No login, no cookies, no Wallapop account.

The scraper collects **item data only**. Wallapop sellers are private individuals, so it never collects seller names, usernames, profile links, phone numbers or e-mail addresses, and it removes phone numbers and e-mails that sellers write into titles and descriptions.

### What you get

| | |
|---|---|
| **Listing** | Item ID, title, price and currency, Wallapop URL, all photos (800 px), photo count |
| **Category** | Top-level category, most specific category, full category path, category ID |
| **Location** | City or town, region, province, country (ES, IT or PT), with no exact coordinates or postal code |
| **Status** | Can be shipped, reserved, refurbished, under warranty, promoted (and how widely: zone, city or country) |
| **Dates** | When the listing was published and when it was last edited |
| **Cars & motorbikes** | Brand, model, year, km, fuel, gearbox, horsepower, version |
| **Real estate** | Sale or rent, property type, m², rooms, bathrooms |
| **Item details** (optional) | Condition, brand, model, size, colour, every attribute (doors, seats, body type, eco label…), views, favourites, chats, hashtags, financed price |
| **Description** (optional) | The seller's text, with phone numbers and e-mails removed |

### How to use it

1. Enter one or more **search terms** (e.g. `bicicleta`, `iphone 13`, `ps5`), or pick a **category** to browse it without a search term.
2. Enter one or more **locations**: a city or town in Spain, Italy or Portugal (`Madrid`, `Barcelona`, `Milano`, `Lisboa`…) or coordinates such as `40.4168, -3.7038`. Set a **distance** in km to stay close, or leave it empty to search the whole country.
3. Optionally set the **sort order**, **price range**, **condition**, **posted within**, **shippable only** and **skip reserved**, then **Max listings**.

You can also paste **Wallapop URLs**. A search URL copied from es.wallapop.com, it.wallapop.com or pt.wallapop.com keeps its keywords, category, location and filters. An item URL scrapes that single listing with full details.

**Max listings** is the total for the run, shared fairly between your search terms and locations. A listing found by two searches is saved and charged once.

#### Input examples

Bikes in Madrid, newest first, €100–€400, as good as new:

```json
{
  "searchTerms": ["bicicleta"],
  "locations": ["Madrid"],
  "distanceKm": 30,
  "sortBy": "newest",
  "minPrice": 100,
  "maxPrice": 400,
  "condition": ["as_good_as_new"],
  "maxItems": 200
}
```

Every car listed today within 50 km of Valencia, with full specs:

```json
{
  "category": "100",
  "locations": ["Valencia"],
  "distanceKm": 50,
  "postedWithin": "today",
  "sortBy": "newest",
  "includeDetails": true,
  "maxItems": 500
}
```

The same search in three cities and two countries:

```json
{
  "searchTerms": ["ps5", "nintendo switch"],
  "locations": ["Barcelona", "Milano", "Lisboa"],
  "distanceKm": 20,
  "maxItems": 300
}
```

Pasted URLs:

```json
{
  "startUrls": [
    { "url": "https://es.wallapop.com/search?keywords=vespa&latitude=41.3874&longitude=2.1686&order_by=price_low_to_high" },
    { "url": "https://es.wallapop.com/item/volkswagen-golf-2016-1300766830" }
  ]
}
```

### Output example

```json
{
  "id": "nzxe2wp2x162",
  "title": "Volkswagen Golf 2016",
  "price": 9999,
  "currency": "EUR",
  "url": "https://es.wallapop.com/item/volkswagen-golf-2016-1300766830",
  "imageUrl": "https://cdn.wallapop.com/images/10420/li/fy/__/c10420p1300766830/i6724066528.jpg?pictureSize=W800",
  "imageCount": 31,
  "categoryId": 100,
  "category": "Coches",
  "categoryPath": ["Coches"],
  "brand": "Volkswagen",
  "model": "Golf",
  "year": 2016,
  "km": 225700,
  "fuel": "Diésel",
  "gearbox": "Semiautomático",
  "horsepower": 110,
  "attributes": { "version": "1.6 TDI CR 110 BMT Edition 5p DSG7", "doors": "5 puertas", "seats": "5 plazas", "eco_label": "Etiqueta C", "body_type": "Pequeño" },
  "city": "Leganés",
  "region": "Comunidad de Madrid",
  "province": "Madrid",
  "countryCode": "ES",
  "shippable": false,
  "reserved": false,
  "promoted": true,
  "promotionType": "country",
  "createdAt": "2026-09-11T18:57:48.417Z",
  "modifiedAt": "2026-10-01T18:01:06.027Z",
  "views": 2380,
  "favorites": 52,
  "chats": 9,
  "itemType": "car",
  "searchCategory": "Cars",
  "searchLocation": "Madrid",
  "position": 1,
  "detailsFetched": true
}
```

Every row has the same 54 columns (see the Output tab). A value Wallapop doesn't show for that listing is `null`. `views`, `favorites`, `chats`, `hashtags`, `conditionText`, `size` and `color` are filled when **Include item details** is on.

### Use cases

- **Reselling and flipping**: catch under-priced items the moment they are posted, with a schedule and **Newest first**.
- **Price research**: what used phones, consoles, bikes or furniture really sell for, by city and condition.
- **Used-car market data**: asking prices by brand, model, year and mileage across Spain.
- **Rental and property snapshots**: rents and sizes from Wallapop's real-estate listings.
- **Demand signals**: views, favourites and chats per listing with item details on.

### FAQ

**Do I need a Wallapop account, cookies or a login?** No. The scraper reads the same public search results any visitor sees on wallapop.com. It never logs in and needs nothing from you except what to search for.

**Which countries work?** Spain, Italy and Portugal, Wallapop's three markets. Each location is searched in its own country's language. Set **Language** to get category names, and Wallapop's translations of titles from other countries, in Spanish, Italian, Portuguese or English.

**Which places can I type?** Nearly 200 cities and big towns in the three countries are built in, with common spellings (`Seville`, `Milan`, `Lisbon`, `Donostia`…). For anywhere else, type coordinates like `41.65, -0.88`. A place the scraper doesn't know is skipped and named in the run's status message.

**How many listings can I get?** Wallapop's own search goes deep: the scraper follows its result pages, 40 listings at a time, until Wallapop runs out or **Max listings** is reached. Set Max listings to 0 for everything.

**How fast is it?** Each page of 40 listings takes about a second, so 1,000 listings take under a minute. **Include item details** adds one quick request per listing, about 2–3 listings per second.

**Why is the condition empty?** Wallapop's search results don't include the condition. Turn on **Include item details**, or filter by exactly one condition, and the column is filled.

**Are seller details included?** No, never. Wallapop is a marketplace of private individuals. The scraper doesn't collect seller names, usernames, profile links, seller IDs, phone numbers or e-mails, and it doesn't give exact coordinates or postal codes. Phone numbers and e-mail addresses in titles and descriptions are replaced with `[phone removed]` and `[email removed]`. Descriptions are only included when you turn them on.

**Which proxy should I use?** Keep the default (Apify Proxy, datacenter). It comes with every Apify plan, including the free one. If Wallapop refuses datacenter IPs for a while, the run switches to residential proxies when your account has them, and carries on without them when it doesn't.

**What does a run cost?** You pay per listing saved, per listing whose item details were read, and a small fee per run. See the Pricing tab. Reserved listings you chose to skip are never charged.

**Is it legal to scrape Wallapop?** This Actor only collects publicly available data: listings that anyone can see on Wallapop without an account, such as titles, prices, categories, photos and the town an item is in. Collecting publicly available data is generally legal, but you're responsible for how you use it. Listings are published by private individuals; the scraper leaves out every seller detail and removes phone numbers and e-mails from listing text. You must follow privacy laws such as GDPR and Spain's LOPDGDD, as well as Wallapop's terms. If you're unsure, check with a lawyer. More on this: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Does it access any private data?** No. Everything comes from what Wallapop shows to any visitor without logging in. It never uses a login, never contacts sellers or sends messages, never opens seller profiles, and follows Wallapop's robots.txt.

*This Actor is not affiliated with, endorsed by or sponsored by Wallapop. Wallapop is a trademark of its owner.*

# Actor input Schema

## `searchTerms` (type: `array`):

What to look for, e.g. "bicicleta", "iphone 13", "ps5". Each term is searched separately in each location. Leave empty to browse a whole category (pick one below).

## `category` (type: `string`):

Only listings in this Wallapop category. With no search term, the run lists the category's newest or most relevant listings near your location.

## `startUrls` (type: `array`):

Paste Wallapop search URLs (es.wallapop.com/search?keywords=…, with any filters you set on the site) or item URLs (es.wallapop.com/item/…). Search URLs keep their filters, category and location.

## `locations` (type: `array`):

Cities or towns in Spain, Italy or Portugal, e.g. "Madrid", "Barcelona", "Milano", "Lisboa", or coordinates as "40.4168, -3.7038". Each location is searched separately. Empty = Madrid.

## `distanceKm` (type: `integer`):

Only listings within this many kilometres of the location. Empty = no distance limit (the whole country, nearest first when sorted by distance).

## `language` (type: `string`):

Language of category names, and of Wallapop's automatic translation of titles from other countries. Auto = the language of the location's country.

## `sortBy` (type: `string`):

Order of the results.

## `minPrice` (type: `integer`):

Only listings at or above this price.

## `maxPrice` (type: `integer`):

Only listings at or below this price.

## `condition` (type: `array`):

Only listings in these conditions (as the seller declared them).

## `postedWithin` (type: `string`):

Only listings published in this period.

## `shippableOnly` (type: `boolean`):

Only listings that can be shipped with Wallapop delivery.

## `skipReserved` (type: `boolean`):

Leave out listings the seller has marked as reserved. Skipped listings are not charged.

## `maxItems` (type: `integer`):

Maximum number of listings for the whole run, shared fairly between your searches and locations. 0 = as many as possible.

## `includeDescription` (type: `boolean`):

Adds the seller's description text. Phone numbers and e-mail addresses in it are removed.

## `includeDetails` (type: `boolean`):

Reads each listing's item record too: condition, brand, model, size, colour, every car or property attribute (doors, seats, body type, eco label…), views, favourites, chats, hashtags and the financed price. One extra request per listing, charged as "Listing details".

## `maxConcurrency` (type: `integer`):

How many item records are read at the same time when "Include item details" is on. Search pages are always read one after another.

## `proxyConfiguration` (type: `object`):

Apify Proxy (datacenter) is the default and comes with every Apify plan. If Wallapop refuses datacenter IPs for a while, the run switches to residential proxies when your account has them.

## Actor input object example

```json
{
  "searchTerms": [
    "bicicleta"
  ],
  "locations": [
    "Madrid"
  ],
  "language": "auto",
  "sortBy": "most_relevance",
  "postedWithin": "any",
  "shippableOnly": false,
  "skipReserved": false,
  "maxItems": 40,
  "includeDescription": false,
  "includeDetails": false,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped listings.

## `run` (type: `string`):

Status and statistics for this run.

## `report` (type: `string`):

RUN_REPORT: how the run ended, counts, requests and proxy use.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "bicicleta"
    ],
    "locations": [
        "Madrid"
    ],
    "maxItems": 40,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/wallapop-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerms": ["bicicleta"],
    "locations": ["Madrid"],
    "maxItems": 40,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("yugenox/wallapop-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "bicicleta"
  ],
  "locations": [
    "Madrid"
  ],
  "maxItems": 40,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call yugenox/wallapop-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yugenox/wallapop-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/piwLYi7rlt6b11gMh/builds/Qyj2VCMZpelg3pHq9/openapi.json
