# Thefork Reviews Scraper (`stealth_mode/thefork-reviews-scraper`) Actor

Scrape verified diner reviews from TheFork.com including ratings, meal dates, reviewer profiles, restaurant replies, and more. Perfect for reputation monitoring, sentiment analysis, and competitive research in the restaurant industry.

- **URL**: https://apify.com/stealth_mode/thefork-reviews-scraper.md
- **Developed by:** [Stealth mode](https://apify.com/stealth_mode) (community)
- **Categories:** Automation, Developer tools, Travel
- **Stats:** 10 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## TheFork Restaurant Reviews Scraper: Extract Ratings & Feedback at Scale

***

### What Is TheFork?

TheFork (formerly LaFourchette) is one of Europe's leading restaurant discovery and reservation platforms, operating across 20+ countries. Each restaurant profile hosts hundreds of verified diner reviews — a goldmine for restaurateurs, marketers, and food-tech developers. The **TheFork Reviews Scraper** automates extraction of this review data, turning pages of feedback into structured, analyzable datasets.

***

### Overview

This scraper targets TheFork restaurant review pages, collecting verified guest feedback with full metadata. It is built for:

- **Restaurant owners** monitoring reputation and tracking guest sentiment
- **F\&B consultants** benchmarking competitors across ratings and keywords
- **Data analysts** building sentiment models on dining experiences
- **Developers** powering review aggregators or hospitality dashboards

Configurable sorting, pagination offset, and per-URL limits make it suitable for both quick snapshots and large-scale bulk collection.

***

### Input Format

```json
{
  "ignore_url_failures": true,
  "max_items_per_url": 200,
  "offset": 0,
  "urls": [
    "https://www.thefork.com/restaurant/bistrot-xvi-r840349/reviews"
  ],
  "sort_by": "RATING-DESC"
}
```

| Field | Type | Description |
|---|---|---|
| `urls` | `array` | One or more TheFork restaurant **review page** URLs (must end in `/reviews`). Add individually or via bulk edit. |
| `sort_by` | `string` | Sort order for reviews. Options: `MEAL_DATE-DESC` *(Newest)*, `RATING-DESC` *(Score high to low)*, `RATING-ASC` *(Score low to low)* |
| `offset` | `integer` | Review index to start from. Use `0` for the beginning; increase to resume from a specific position (e.g., `100` to skip the first 100 reviews). |
| `max_items_per_url` | `integer` | Maximum reviews to collect per URL. Default prefill: `20`. Set higher (e.g., `200`) for comprehensive collection. |
| `ignore_url_failures` | `boolean` | If `true`, failed URLs are skipped rather than stopping the entire run — recommended for bulk jobs. |

> **Tip:** To collect only negative reviews for analysis, use `sort_by: "RATING-ASC"`. To collect the most recent feedback, use `"MEAL_DATE-DESC"`.

***

### Output Format

#### Sample Record (abbreviated)

```json
{
  "id": "005991a0-fd58-43bf-ab23-a9cdbe297584",
  "uuid": "005991a0-fd58-43bf-ab23-a9cdbe297584",
  "rating_value": 10,
  "meal_date": "2025-12-06T12:45:00.000Z",
  "review": {
    "review_body": "très bien positionné. La serveuse a su gérer en étant toute seule. top !",
    "__typename": "RatingReview"
  },
  "reviewer": {
    "id": "376e7cbf-e63c-4606-b6d2-29ad31b3f357",
    "avatar_url": "https://cdn.thefork.com/tf-lab/image/upload/v1779222864/avatar/376e7cbf-e63c-4606-b6d2-29ad31b3f357.png",
    "first_name": "vincent",
    "last_name": "d.",
    "review_count": 48,
    "__typename": "Reviewer"
  },
  "restaurant_reply": null,
  "photos": [],
  "likes": 0,
  "keywords_position": null,
  "from_url": "https://www.thefork.com/restaurant/bistrot-xvi-r840349/reviews"
}
```

Each record represents one verified diner review with the following fields:

#### Core Review Data

| Field | Meaning |
|---|---|
| `ID` | Internal numeric identifier for the review |
| `UUID` | Universally unique identifier — useful as a stable key when deduplicating across runs |
| `Rating Value` | Numerical score given by the diner (typically on TheFork's 10-point scale) |
| `Meal Date` | The date the diner visited the restaurant (not the date the review was posted) |
| `Review` | Full text of the diner's written feedback |

#### Reviewer & Response

| Field | Meaning |
|---|---|
| `Reviewer` | Profile metadata of the person who left the review (may include display name, reviewer tier) |
| `Restaurant Reply` | The restaurant's official response to the review, if one exists — useful for tracking engagement quality |

#### Enrichment Fields

| Field | Meaning |
|---|---|
| `Photos` | Images attached to the review by the diner |
| `Likes` | Number of "helpful" or like reactions the review has received from other users |
| `Keywords Position` | Structured keyword or tag data associated with the review — may indicate dish mentions, service aspects, or TheFork-generated topic tags |

***

### How to Use

1. **Get the review URL** — Navigate to any restaurant on TheFork and go to the *Reviews* tab. Copy the URL (format: `.../restaurant/[name]-r[id]/reviews`).
2. **Configure input** — Paste the URL(s), set `sort_by` and `max_items_per_url` to match your needs.
3. **Set offset if resuming** — Use `offset` to paginate large datasets across multiple runs.
4. **Run and export** — Download results as JSON or CSV for use in Excel, Google Sheets, or your data pipeline.

**Common issues:**

- If no data is returned, confirm the URL ends in `/reviews` — product or menu pages will not work.
- TheFork may vary page structure by country/locale; test with one URL before bulk runs.

***

### Use Cases & Business Value

- **Reputation management:** Track rating trends over time and flag negative feedback early
- **Competitor benchmarking:** Compare review volumes, average scores, and response rates across restaurants
- **Sentiment analysis:** Feed review text into NLP pipelines to extract topics and sentiment at scale
- **Menu intelligence:** Mine `Keywords Position` and review text for frequently mentioned dishes

***

### Conclusion

The **TheFork Reviews Scraper** delivers structured, verified dining feedback at scale — eliminating hours of manual reading and copy-pasting. Whether you're managing a single venue or analyzing hundreds of competitors, it provides the raw material for data-driven hospitality decisions.

# Actor input Schema

## `urls` (type: `array`):

Add the URLs of the Restaurant details urls you want to scrape. You can paste URLs one by one, or use the Bulk edit section to add a prepared list.

## `sort_by` (type: `string`):

Select your option to sort reviews

## `offset` (type: `integer`):

Offset to start from

## `ignore_url_failures` (type: `boolean`):

If true, the scraper will continue running even if some URLs fail to be scraped.

## `max_items_per_url` (type: `integer`):

The maximum number of items to scrape per URL.

## Actor input object example

```json
{
  "urls": [
    "https://www.thefork.com/restaurant/bistrot-xvi-r840349/reviews"
  ],
  "ignore_url_failures": true,
  "max_items_per_url": 20
}
```

# 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 = {
    "urls": [
        "https://www.thefork.com/restaurant/bistrot-xvi-r840349/reviews"
    ],
    "offset": 0,
    "ignore_url_failures": true,
    "max_items_per_url": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("stealth_mode/thefork-reviews-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 = {
    "urls": ["https://www.thefork.com/restaurant/bistrot-xvi-r840349/reviews"],
    "offset": 0,
    "ignore_url_failures": True,
    "max_items_per_url": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("stealth_mode/thefork-reviews-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 '{
  "urls": [
    "https://www.thefork.com/restaurant/bistrot-xvi-r840349/reviews"
  ],
  "offset": 0,
  "ignore_url_failures": true,
  "max_items_per_url": 20
}' |
apify call stealth_mode/thefork-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,stealth_mode/thefork-reviews-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/aioxDUd9dbZXrdyfv/builds/YRm8oMNagvpEnVQ4T/openapi.json
