Skip to main content

Complete Guide: How to Scrape Vinted Spain Listings Using Python

Run the Vinted Spain Scraper Actor from Python to extract secondhand clothes, footwear, prices, condition, and seller type as clean JSON rows.

Updated 12 min readMarkdown
Complete Guide: How to Scrape Vinted Spain Listings Using Python

This complete guide to Vinted Spain Scraper shows how to collect secondhand apparel, footwear, accessories, and home items from vinted.es using Python and the Apify API. Instead of manually clicking through search pages or copying catalog items by hand, you configure search parameters in Python and receive structured rows: item title, item price in euros, buyer protection service fee, total price, currency, brand, condition, size, photo URL, favourite counts, and seller classification.

A marketplace search such as "nike" returns pre-owned listings across varying conditions and seller tiers. The Actor queries Vinted Spain directly, sends condition and price filters with the search, applies keyword and seller-type filters to what comes back, and streams structured records to a centralized dataset. This tutorial walks through setting up the environment, configuring parameters for targeted searches, executing the Actor, and analyzing the resulting data.

Minimal technical prerequisites are required: a Python 3 environment, a terminal, and an Apify account token. Estimated time to complete: About 30 minutes. The benchmark run cited throughout this tutorial (started on 2026-10-23 with searchQueries: ["nike"], conditions: ["Muy bueno", "Bueno"], minPrice: 10, maxPrice: 40, sortBy: "relevance", requireKeywordMatch: true, maxItems: 200) returned 200 structured rows in 19.2 seconds.


TL;DR

In this tutorial, you'll learn to run the Vinted Spain Scraper Actor from Python, extract pre-owned fashion listings from vinted.es, and filter by item condition, price band, and seller category. Key steps: install apify-client, configure your API token, define run_input with search terms and filtering criteria, call the Actor, and iterate over dataset records.

Expected outcome: 200 typed rows for the cited run, each with title, item price, buyer protection service fee, total price, currency, brand, condition, size, favourite count, and listing URL, ready for price analysis, resale tracking, or database ingestion.

The Actor is available at apify.com/reventadata/vinted-scraper.


Prerequisites and setup

To follow this tutorial, you need three prerequisites:

  1. Python 3 installed on your local computer.
  2. The official Apify API client library for Python, installed via pip.
  3. An active Apify account with a personal API token.

Apify Console is the web interface where your scrapers, scheduled tasks, storage datasets, and integration credentials reside. Your personal API token is located on the API & Integrations tab in Apify Console. Official platform documentation is available at docs.apify.com.

Install the Apify Python client:

pip install "apify-client~=3.0"

Keep your personal API token secure and out of version control. In the demonstration scripts below, replace the placeholder <YOUR_APIFY_TOKEN> with your real API token or load it from an environment variable in your production configuration.


Understanding Vinted Spain Scraper

Vinted Spain Scraper (reventadata/vinted-scraper) searches vinted.es for any keyword or category and outputs matching listings as structured records, up to the maxItems and maxPages caps. Behind the scenes, Vinted delivers catalog pages through a server-rendered Next.js stream. The Actor decodes the embedded catalog payload and parses the listings directly, eliminating the need to manage browser-minted session cookies.

Key capabilities:

  • Direct connection: Operates cleanly on direct HTTP requests without requiring proxy rotation or unblocker services.
  • Price and fee transparency: Separates the item price, Vinted buyer protection service fee, and total payable price into individual numeric columns.
  • Catalogue metadata extraction: Recovers brand, model, condition, and size attributes directly from rendered item metadata.
  • Seller classification: Identifies private versus professional sellers while maintaining strict privacy standards by leaving seller identifiers out of private-seller rows.
  • Keyword matching: Enforces keyword presence across title, brand, and model when requireKeywordMatch is enabled.

Limitation to note: Vinted serves at most 10 pages of 96 items (960 items) per query to anonymous visitors, so maxPages is clamped to 10.


Step-by-step walkthrough

Step 1: Accessing the Actor

Open the Vinted Spain Scraper page on the Apify Store. The store listing details input options, output schemas, and current documentation. While you can trigger runs directly from the Apify Console web interface, running the Actor programmatically from Python enables seamless integration into automated data pipelines and monitoring jobs.

Step 2: Configuring input parameters

The Actor accepts a JSON input object. The core fields configured in this guide include:

Field Type Description
searchQueries array Search terms, one search per term (e.g. ["nike"]).
conditions array List of condition titles to retain (e.g. ["Muy bueno", "Bueno"]).
minPrice integer Optional minimum item price in EUR (omitted when unset).
maxPrice integer Optional maximum item price in EUR (omitted when unset).
sortBy string Sort order: relevance, priceAsc, priceDesc, or newest.
requireKeywordMatch boolean Require query words in title, brand, or model (default: true).
sellerType string Seller filter: any, private, or professional (default: any).
maxItems integer Hard cap on total rows pushed across all queries (default: 960).
maxPages integer Maximum pages per query, up to 96 items per page (default: 10).

Three example configurations:

  • Budget Nike apparel (used in this guide): {"searchQueries": ["nike"], "conditions": ["Muy bueno", "Bueno"], "minPrice": 10, "maxPrice": 40, "sortBy": "relevance", "requireKeywordMatch": true, "maxItems": 200}
  • Cheapest vintage leather jackets: {"searchQueries": ["chaqueta cuero vintage"], "sortBy": "priceAsc", "maxItems": 100}
  • Category browsing without keywords: {"catalogIds": [2994], "minPrice": 20, "maxPrice": 150, "maxItems": 150}

Step 3: Advanced configuration

Beyond basic keyword queries, the Actor provides parameters for specialized catalog collection:

  • catalogIds: Numerical category identifiers from the site (such as 2994 for Electronics or 1904 for Women). When supplied without keywords, the Actor browses the category.
  • brandIds: Numerical brand identifiers from category filter panels (such as 105 for Primark or 7 for H&M).
  • sellerType: Filters listings by seller category (any, private, or professional), evaluated from Vinted seller metadata after fetching.
  • requireKeywordMatch: Drops items whose title, brand, and model are missing any word of the query, preventing loosely matched category recommendations from cluttering your dataset.

Step 4: Optional seller and condition filters

On Vinted Spain, listings are predominantly submitted by private individuals, with professional business accounts at 4 of 200 rows (2.0%) in this run. Configuring sellerType: "private" excludes business listings, whereas sellerType: "professional" isolates commercial sellers. Similarly, conditions sends the chosen condition grades to Vinted with the search.

Step 5: Running the Actor

The following Python script initializes the client, configures the input used in our benchmark run, triggers the Actor, and prints the extracted items:

from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run_input = {
    "searchQueries": ["nike"],
    "conditions": [
        "Muy bueno",
        "Bueno",
    ],
    "minPrice": 10,
    "maxPrice": 40,
    "sortBy": "relevance",
    "requireKeywordMatch": True,
    "maxItems": 200,
}

run = client.actor("reventadata/vinted-scraper").call(run_input=run_input)

for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item["title"], item["price"], item["totalPrice"], item["currency"], item["url"])

Calling .call() starts the run and blocks until completion. The cited benchmark run finished with status SUCCEEDED in 19.2 seconds and pushed 200 rows.

Step 6: Examining the results

The dataset items can be inspected directly in Apify Console or consumed programmatically via iterate_items(). The first record from our benchmark run is shown below:

{
  "id": "10500531689",
  "title": "T shirt Nike",
  "url": "https://www.vinted.es/items/10500531689-t-shirt-nike",
  "price": 10,
  "serviceFee": 1.2,
  "totalPrice": 11.2,
  "currency": "EUR",
  "brand": "Nike",
  "model": null,
  "condition": "Muy bueno",
  "size": "XS",
  "photoUrl": "https://images1.vinted.net/t/05_0215e_JV2wBP59Ao9gQftFrYkxAL2K/310x430/212da0d0.webp?s=859bad0c545f8fa148f97e7eb0afcff61240411b",
  "favouriteCount": 51,
  "isPromoted": false,
  "sellerType": "private",
  "matchedKeyword": "nike"
}

In this record, price is 10 EUR and serviceFee is 1.20 EUR, producing a totalPrice of 11.20 EUR. The brand is parsed as Nike, condition is Muy bueno, size is XS, and favouriteCount records 51 user saves.

Step 7: Downloading and exporting data

The dataset can be exported from Apify Console or downloaded programmatically in JSON, CSV, Excel or JSONL formats. JSON preserves structured fields such as image links, while CSV and Excel formats flatten columns for spreadsheet analysis and pricing audits.


Working with the API

The Python script above uses the synchronous .call() method from the apify-client package, which blocks until the run completes and returns a Run object. For automated data ingestion pipelines or microservices, you may prefer an asynchronous execution model where you trigger the Actor and disconnect immediately:

run = client.actor("reventadata/vinted-scraper").start(run_input=run_input)
print(f"Started run with ID: {run.id}, status: {run.status}")

Once started, you can store run.id and fetch the dataset at a later time. To retrieve results from a completed run, access the dataset through client.dataset(run.default_dataset_id). You can stream items sequentially using iterate_items() or fetch a specific page of items using list_items(offset=0, limit=100).

Authentication is managed via your API token provided to the ApifyClient constructor. For event-driven architectures, you can configure an Apify webhook to listen for the ACTOR.RUN.SUCCEEDED event. The webhook delivers the run resource payload containing defaultDatasetId directly to your HTTP endpoint (docs.apify.com/platform/integrations/webhooks/actions), allowing your backend to download dataset records without polling.

Error handling is critical in production pipelines: always verify that run.status == "SUCCEEDED" before consuming dataset records. If Vinted Spain Scraper pushes zero rows, it raises a RuntimeError rather than completing silently. If all retrieved listings are excluded by filters, the Actor raises a RuntimeError noting that all parsed listings were rejected by the filters; if the site returned no listings at all, it raises a RuntimeError indicating zero results.


Advanced usage patterns

1. Category browsing without keywords

You can browse Vinted categories without passing a search keyword. Supply category identifiers in catalogIds, such as [2994] for Electronics or [1904] for Women's fashion, while leaving searchQueries empty. The Actor treats empty keywords with category IDs as legitimate broad sweeps, iterating through category pages up to the requested maxItems cap.

2. Catalogue brand targeting

Combine brandIds with price thresholds to isolate specific designer or sportswear collections. Because brand identifiers are catalogue-scoped on Vinted, retrieve brand IDs directly from category filter checkboxes on the site before passing them to the Actor.

3. Scheduled apparel price tracking

To monitor market price drops and newly listed secondhand items over time, run the Actor on a recurring schedule. Apify schedules allow you to trigger Actors automatically using cron expressions (docs.apify.com/platform/schedules). By comparing sequential runs by id, you can detect when an item is marked down or removed from the catalog.

4. Seller segmentation

Set sellerType: "professional" to extract listings only from sellers Vinted flags as business accounts, or sellerType: "private" to monitor deals from individual closets. For professional sellers, the Actor extracts public business profile links, while private-seller rows carry no seller identifiers.


Understanding your data

Each dataset row represents a Vinted Spain listing with structured attributes:

  • id, title, url: Unique listing identifier, title, and canonical URL.
  • price, serviceFee, totalPrice, currency: Item price, buyer protection fee, total price in EUR.
  • brand, model, condition, size: Extracted clothing attributes.
  • photoUrl, favouriteCount, isPromoted: Image link, favourite saves, promotion flag.
  • sellerType, sellerId, sellerProfileUrl: Seller classification and business profile URLs.
  • matchedKeyword: The search term that produced the item.

The cited run on 2026-10-23 extracted 200 products for "nike". Item prices ranged from 10 to 40 EUR (median 12.0, mean 15.11 EUR), with service fees from 1.20 to 2.70 EUR (median 1.30, mean 1.46 EUR) and total prices from 11.20 to 42.70 EUR (median 13.30, mean 16.57 EUR). All 200 matched requested conditions: 173 were "Muy bueno" and 27 were "Bueno". By seller classification, 196 listings were from private sellers and 4 from professional sellers. Across the 200 rows, 139 were organic and 61 promoted. Favourite counts ranged from 0 to 83 (median 15.0, mean 20.43), with 4 items recording 0 favourites. Sizing spanned 41 distinct labels, with 1 item showing a null size. The model attribute was null across all 200 rows.


Troubleshooting guide

  • The run fails with "No rows pushed": If all retrieved listings are excluded by filters or if a query yields no items, the Actor raises a RuntimeError so that pipelines detect the failure immediately. Loosen restrictive filters such as conditions, minPrice, maxPrice, or sellerType, and verify on vinted.es that the term returns items.
  • Input rejected prior to execution: sortBy is validated against supported values (relevance, priceAsc, priceDesc, newest). An unsupported sort value is refused before the run starts. An empty searchQueries list without catalogIds makes the Actor raise a ValueError before page processing begins.
  • Anonymous page limit reached: Vinted serves at most 10 pages (960 items) per query to anonymous visitors. The Actor clamps maxPages to 10. To extract deeper catalogs, segment your search by price bands, brand IDs, or category identifiers.
  • Fewer rows than maxItems: The search term may have fewer products than your requested maximum, or the query may have exhausted available pages within the maxPages ceiling.
  • Reading execution logs: Inspect the execution log in Apify Console. At completion, the Actor logs how many rows it pushed.

Best practices

  1. Always set maxItems and maxPages. Set explicit caps to prevent over-scraping broad queries; each result page yields up to 96 products.
  2. Rely on direct connections. Vinted Spain Scraper ran on direct outbound connections, with no proxy configured, in the cited run.
  3. Filter condition and price at the Actor level. Configure conditions, minPrice, and maxPrice directly in run_input rather than post-processing, so unwanted rows never consume dataset storage.
  4. Target exact matches. Keep requireKeywordMatch: true enabled to drop tangential category items that omit your search query terms.
  5. Segment large catalogs. To handle the 10-page anonymous ceiling on broad searches, split queries across specific brandIds, catalogIds, or price bands.
  6. Automate on a schedule. Deploy scheduled runs with Apify schedules to capture daily additions and new price markdowns.

Pricing

For current pricing and details, see the Store page.


Conclusion and next steps

You now have a functional Python script to extract structured fashion listings, pricing, buyer fees, and conditions from vinted.es. By supplying a search term, configuring condition and price filters, and iterating over the dataset, you can integrate fresh secondhand market data into price tracking applications or inventory analytics workflows.

Explore the Apify documentation to learn more about scheduling runs, configuring webhooks, and exporting datasets. Visit the Vinted Spain Scraper page to review the input schema and test different fashion categories.

Try Vinted Spain Scraper yourself and let me know what you build!


About the author: reventadata builds data extraction tools on the Apify Store.

About the author

  • Hi, I’m the engineer behind ReventaData. I build automated web scrapers, reverse-engineer undocumented APIs, and design data pipelines on Apify that turn complex, unstructured websites into clean, reliable feeds. Here on Hashnode, I share practical tutorials on modern web scraping with Python, bypassing aggressive anti-bot protections (Cloudflare, Akamai, PerimeterX), and data pipeline automation, reverse-engineering hidden endpoints, and automating data extraction. Explore our turnkey scrapers: https://apify.com/reventadata

No comments yet. Be the first to comment.

More from this blog