# Resto.be Scraper — Belgian Restaurant Data & Reviews (`studio-amba/resto-scraper`) Actor

Scrape restaurant data from Resto.be — names, addresses, cuisine types, ratings, Michelin stars, Gault\&Millau scores, and opening hours for Belgian restaurants.

- **URL**: https://apify.com/studio-amba/resto-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Lead generation
- **Features:** Limited permissions
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 result scrapeds

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

## Resto.be Scraper -- Belgian Restaurants, Michelin Stars & Gault Millau Scores

Scrape restaurant listings from [Resto.be](https://www.resto.be) -- Belgium's largest restaurant guide featuring over 20,000 restaurants with ratings, cuisine types, Michelin stars, Gault Millau scores, contact details, opening hours, and payment information.

### What is Resto.be Scraper?

Resto.be is Belgium's most comprehensive restaurant directory. It covers the entire country -- from Michelin-starred fine dining in Brussels to neighbourhood bistros in Namur and frituren in Ostend. What makes Resto.be valuable is its combination of user ratings with professional guide scores: Michelin stars and Gault Millau points are displayed alongside consumer reviews, creating the most complete picture of Belgian dining available anywhere.

This actor scrapes restaurant detail pages, extracting structured data from both JSON-LD markup and HTML parsing. It supports pagination through city and region listing pages to collect data at scale. What people build with it:

- **Restaurant market intelligence** -- food industry suppliers, real estate developers, and franchise operators analyse the Belgian restaurant landscape by city, cuisine type, and quality tier to identify market gaps and expansion opportunities.
- **Fine dining databases** -- luxury travel platforms and concierge services build curated databases of Michelin and Gault Millau rated restaurants across Belgium.
- **Competitive analysis** -- restaurant owners and restaurant groups benchmark themselves against nearby competitors on ratings, pricing, and cuisine offerings.
- **Food tourism planning** -- tour operators and travel agencies build Belgian gastronomic itineraries using restaurant locations, cuisine types, and quality ratings.
- **Data journalism** -- journalists and researchers analyse patterns in Belgian dining -- which cities have the most Michelin stars, how cuisines distribute across regions, where new restaurants concentrate.

### What data does Resto.be Scraper extract?

Each restaurant record includes:

- :fork_and_knife: **Name** -- the restaurant name
- :house: **Address** -- street address, postal code, and city
- :world_map: **Coordinates** -- latitude and longitude for mapping
- :telephone: **Phone** -- contact number
- :globe_with_meridians: **Website** -- the restaurant's own website URL
- :stew: **Cuisine types** -- array of cuisine categories (Belgisch, Frans, Italiaans, Japans, etc.)
- :money_with_wings: **Price range** -- price category indicator
- :star: **Rating** -- consumer rating score
- :writing_hand: **Review count** -- number of user reviews
- :medal: **Michelin stars** -- 1, 2, or 3 Michelin stars when applicable
- :trophy: **Gault Millau score** -- score out of 20 from the Gault Millau guide
- :credit_card: **Payment methods** -- accepted payment options
- :sparkles: **Features** -- amenities and services (terrace, parking, private dining, etc.)
- :clock1: **Opening hours** -- structured by day of week
- :memo: **Description** -- the restaurant's profile text
- :framed_picture: **Image** -- main restaurant photo

### How to scrape Belgian restaurants

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `startUrls` | Array | No | City or region listing pages, e.g. `https://www.resto.be/restaurant/bruxelles` |
| `searchQuery` | String | No | City name or cuisine: `"bruxelles"`, `"gent"`, `"italian"` |
| `maxResults` | Integer | No | Maximum restaurants to return (default: 100, max: 50,000) |
| `language` | String | No | `"fr"` (default, www.resto.be), `"nl"` (nl.resto.be), `"en"` (en.resto.be) |
| `proxyConfiguration` | Object | No | Proxy settings (recommended for 1,000+ restaurants) |

**Tips:**

- Start with a specific city for focused results: `searchQuery: "bruxelles"` or `searchQuery: "gent"`.
- For a complete Belgian restaurant database, run multiple times with different cities or set a high `maxResults` from the main listing page.
- Use `language: "nl"` for Dutch-language descriptions and cuisine names, `"fr"` for French.
- The actor handles pagination automatically via the `window.RESTO.pager` data or "suivant/volgende" links.

### Output

```json
{
    "name": "Comme Chez Soi",
    "address": "Place Rouppe 23",
    "city": "Bruxelles",
    "postalCode": "1000",
    "latitude": 50.8432,
    "longitude": 4.3465,
    "phone": "+32 2 512 29 21",
    "website": "https://www.commechezsoi.be",
    "cuisine": ["Gastronomique", "Francaise", "Belge"],
    "priceRange": "$$$$",
    "rating": 9.2,
    "reviewCount": 187,
    "michelinStars": 2,
    "gaultMillauScore": 18.5,
    "paymentMethods": ["Visa", "Mastercard", "American Express"],
    "features": ["Terras", "Parking", "Prive-eetruimte"],
    "openingHours": {
        "Dinsdag": "12:00-14:00, 19:00-22:00",
        "Woensdag": "12:00-14:00, 19:00-22:00",
        "Donderdag": "12:00-14:00, 19:00-22:00",
        "Vrijdag": "12:00-14:00, 19:00-22:00",
        "Zaterdag": "19:00-22:00"
    },
    "description": "Comme Chez Soi is een legendarisch Brusselse gastronomische adres in art nouveau stijl...",
    "imageUrl": "https://www.resto.be/media/restaurants/comme-chez-soi.jpg",
    "restoId": "12345",
    "url": "https://www.resto.be/restaurant/bruxelles/1000-centre/12345-comme-chez-soi",
    "language": "fr",
    "scrapedAt": "2026-04-03T13:00:00.000Z"
}
```

### How much does it cost?

Resto.be Scraper uses CheerioCrawler (no browser needed):

| Volume | Estimated CUs | Estimated Cost |
|--------|--------------|----------------|
| 100 restaurants | ~0.03 | ~$0.015 |
| 500 restaurants | ~0.12 | ~$0.06 |
| 1,000 restaurants | ~0.25 | ~$0.13 |
| 5,000 restaurants | ~1.10 | ~$0.55 |

The actor first collects restaurant URLs from listing pages, then visits each detail page. Costs scale linearly.

### Can I integrate?

Push Belgian restaurant data into your tools:

- **Google Sheets** -- build a sortable restaurant database filtered by Michelin stars, city, or cuisine
- **Google Maps / Mapbox** -- plot restaurants on an interactive map using coordinates
- **Slack** -- weekly digest of newly added or updated restaurants in your city
- **Zapier / Make** -- trigger workflows when new Michelin-starred restaurants appear
- **PostgreSQL / MongoDB** -- feed a searchable restaurant API for your app
- **Power BI / Tableau** -- visualise the Belgian dining landscape by region and quality tier

### Can I use it as an API?

Yes. Build Belgian gastronomy intelligence into your product:

**Python:**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("studio-amba/resto-scraper").call(run_input={
    "searchQuery": "bruxelles",
    "language": "fr",
    "maxResults": 500,
})

for restaurant in client.dataset(run["defaultDatasetId"]).iterate_items():
    stars = f" {'*' * restaurant['michelinStars']}" if restaurant.get('michelinStars') else ""
    print(f"{restaurant['name']}{stars} - {', '.join(restaurant.get('cuisine', []))}")
```

**JavaScript:**

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

const client = new ApifyClient({ token: "YOUR_API_TOKEN" });

const run = await client.actor("studio-amba/resto-scraper").call({
    searchQuery: "gent",
    language: "nl",
    maxResults: 300,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
const starred = items.filter((r) => r.michelinStars > 0);
console.log(`Found ${starred.length} Michelin-starred restaurants in Gent`);
starred.forEach((r) => console.log(`  ${"*".repeat(r.michelinStars)} ${r.name}`));
```

### FAQ

**Does Resto.be cover all of Belgium?**
Yes. Resto.be covers Brussels, Flanders, and Wallonia. It is the most comprehensive Belgian restaurant directory available.

**Are Michelin stars and Gault Millau scores always present?**
Only for restaurants that have received these awards. The vast majority of restaurants will not have Michelin or Gault Millau data. The fields are only present when applicable.

**How accurate is the data?**
Resto.be data is maintained by restaurant owners and the platform team. Like any directory, some entries may be outdated (closed restaurants, changed hours). The `rating` and `reviewCount` reflect current platform data.

**Can I filter by Michelin stars only?**
Not as an input filter, but every result includes the `michelinStars` field. Scrape a city and filter the output for `michelinStars > 0`.

**Is there duplicate data between language versions?**
The same restaurants appear on www.resto.be (French), nl.resto.be (Dutch), and en.resto.be (English) with translated descriptions but the same underlying data.

**What is the `restoId` field?**
A numeric identifier extracted from the URL, useful for deduplication when scraping multiple cities or language versions.

### Limitations

- Some restaurant detail pages may not have JSON-LD structured data, falling back to less precise HTML parsing.
- Opening hours and payment methods depend on whether the restaurant owner has kept their Resto.be profile up to date.
- Gault Millau scores are extracted from page content with pattern matching. Unusual formatting may be missed.
- Large city scrapes (all of Brussels, all of Antwerp) require proxy configuration to avoid rate limiting.
- The actor does not extract individual user reviews -- only aggregate ratings and review counts.

### Related Belgian and food scrapers

- [HelloFresh Scraper](https://apify.com/studio-amba/hellofresh-scraper) -- Belgian meal kit recipes, ingredients, and nutrition data
- [UiTinVlaanderen Scraper](https://apify.com/studio-amba/uitinvlaanderen-scraper) -- Flemish cultural events (food festivals, culinary events)
- [VDAB Scraper](https://apify.com/studio-amba/vdab-scraper) -- Flemish job listings (restaurant industry hiring)
- [NMBS Scraper](https://apify.com/studio-amba/nmbs-scraper) -- train connections to reach restaurants across Belgium

### Your feedback

Want to track restaurant openings and closings, need individual review text, or found a parsing issue? Open an issue on GitHub or contact us through the Apify platform. We prioritise improvements based on user demand.

# Actor input Schema

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

Resto.be city or region listing pages to scrape. Example: https://www.resto.be/restaurant/bruxelles or https://nl.resto.be/restaurant/gent

## `searchQuery` (type: `string`):

Search by city name or cuisine type (e.g., 'bruxelles', 'gent', 'italian'). Used to build listing URLs if no startUrls provided.

## `maxResults` (type: `integer`):

Maximum number of restaurants to return.

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

Language for restaurant data. French uses www.resto.be, Dutch uses nl.resto.be, English uses en.resto.be.

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

Proxy settings. Recommended for scraping more than 1,000 restaurants.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.resto.be/restaurant/bruxelles"
    }
  ],
  "maxResults": 100,
  "language": "fr"
}
```

# Actor output Schema

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

No description

# 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 = {
    "startUrls": [
        {
            "url": "https://www.resto.be/restaurant/bruxelles"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/resto-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 = { "startUrls": [{ "url": "https://www.resto.be/restaurant/bruxelles" }] }

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/resto-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 '{
  "startUrls": [
    {
      "url": "https://www.resto.be/restaurant/bruxelles"
    }
  ]
}' |
apify call studio-amba/resto-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/resto-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/AKpovzEbfac9FTNmL/builds/qC1CR1AVbn13e0HH1/openapi.json
