# Recipe Scraper (`mina_safwat/recipe-scraper`) Actor

Extracts structured recipes — ingredients, steps, times, nutrition, and ratings — from 725+ recipe sites.

- **URL**: https://apify.com/mina\_safwat/recipe-scraper.md
- **Developed by:** [Mina](https://apify.com/mina_safwat) (community)
- **Categories:** News, E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

Turn any **recipe page into structured data** — ingredients, numbered steps, prep and cook times, nutrition, ratings, and yield — from 725 recipe sites and thousands more that publish standard recipe markup.

### What does Recipe Scraper do?

Give it recipe URLs and it returns clean, machine-readable recipes: the ingredient list, the instructions as separate steps, total, prep and cook times in minutes, servings, nutrition facts, the star rating and how many people rated it, plus the cuisine, course, and author.

725 sites are supported directly, and most others work too, because the Actor also reads the standard recipe information that food sites publish. You are not limited to a fixed list.

### Why use Recipe Scraper?

- **Recipe apps and meal planners** — build a database without hand-entering anything.
- **Nutrition analysis** — pull calories and macros across hundreds of recipes at once.
- **Shopping list tools** — the ingredient list arrives already separated, line by line.
- **Content research** — compare how sites treat the same dish, or track ratings over time.
- **AI training data** — structured ingredients and steps are far more useful than raw HTML.

Running it on Apify adds scheduling, an API, integrations (Sheets, Slack, Zapier, S3), residential proxy rotation, and run monitoring.

### How to use Recipe Scraper

1. Paste recipe links into **Recipe URLs**, one per line.
2. Click **Start**.

That is the whole setup. Results appear in the Output tab as they are scraped, and download as JSON, CSV, Excel, or XML.

### Input

| Field | Description |
| --- | --- |
| `recipe_urls` | Links to recipe pages, one per line. |
| `max_recipes` | Stops after this many URLs. |
| `allow_unsupported_sites` | Try any site, not only the 725 supported ones. On by default. |
| `max_concurrency` | How many pages to fetch at once. Lower it if a site rate-limits you. |
| `proxy_country` | Comma-separated country codes for the residential proxy rotation. |

### Output

```json
{
  "url": "https://www.allrecipes.com/recipe/20144/banana-banana-bread/",
  "title": "Banana Banana Bread",
  "author": "Shelley Albeluhn",
  "site_name": "Allrecipes",
  "description": "An incredibly moist loaf with very ripe bananas.",
  "image": "https://www.allrecipes.com/thmb/lead.jpg",
  "yields": "1 loaf",
  "total_time_minutes": 75,
  "prep_time_minutes": 15,
  "cook_time_minutes": 60,
  "ingredients": [
    "2 cups all-purpose flour",
    "1 teaspoon baking soda",
    "3 ripe bananas, mashed"
  ],
  "instruction_steps": [
    "Heat the oven to 175 degrees C.",
    "Combine the dry ingredients.",
    "Fold in the bananas and bake for an hour."
  ],
  "nutrients": { "calories": "231 kcal", "proteinContent": "4 g" },
  "rating": 4.7,
  "rating_count": 17388,
  "category": "Breakfast",
  "cuisine": "American",
  "has_dedicated_scraper": true
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

#### Data fields

| Field | Description |
| --- | --- |
| `title`, `description`, `author`, `image` | The recipe and who wrote it. |
| `ingredients` | One line per ingredient, as written. |
| `ingredient_groups` | Ingredients split by section — "For the sauce", "For the topping" — where the site groups them. |
| `instructions`, `instruction_steps` | The method as one block, and as separate numbered steps. |
| `total_time_minutes`, `prep_time_minutes`, `cook_time_minutes` | Times as plain numbers, not text. |
| `yields` | Servings or quantity. |
| `nutrients` | Calories and macros, as the site publishes them. |
| `rating`, `rating_count` | Star rating and how many people rated it. |
| `category`, `cuisine`, `cooking_method`, `dietary_restrictions`, `keywords` | Classification. |
| `has_dedicated_scraper` | Whether this site is one of the 725 supported directly. |
| `error` | Present only when a page could not be read, with the reason. |

### How much does it cost to scrape recipes?

Cost tracks the number of recipe links you give it, so **Max recipes** is the main lever on what a run costs.

### Tips

- **Check `has_dedicated_scraper`.** Directly supported sites tend to fill in more fields, especially nutrition and grouped ingredients.
- **Lower the concurrency** to 1 or 2 if a single site starts refusing requests.
- **Rows are never dropped.** A URL that fails still gets written, with an `error` saying why — so a large run never loses track of which inputs worked.

### FAQ and support

**Which sites are supported?** 725 directly, plus most others — the Actor also reads the standard recipe information that food sites publish.

**Why did a site return "no recipe data"?** A few sites do not publish their recipe in a readable form, and some links simply are not recipe pages. Those come back as an `error` row rather than failing the whole run.

**Why are some fields empty?** Not every site publishes prep time, nutrition, or a rating. When a site does not declare it, the field comes back empty rather than guessed.

**Why did a recipe come back with ingredients but no method?** A few sites — Simply Recipes among them — publish their ingredient list but not their instructions. Those recipes still come through, with the steps empty, and the run log names each one so you can spot them.

**Is scraping recipes legal?** Ingredient lists are generally facts rather than creative work, but the surrounding text, photos, and the recipe as written are usually copyrighted. Extracting for personal use, analysis, or research is common; republishing is a different matter. You are responsible for how you use the output, including each site's terms. Consult a lawyer if you are unsure.

Found a bug or want a field that is missing? Open an issue on the Actor's Issues tab.

# Actor input Schema

## `recipe_urls` (type: `array`):

Links to recipe pages, one per line. 725 sites have a dedicated extractor; others are read from the standard recipe markup most sites publish.

## `max_recipes` (type: `integer`):

Stops after this many URLs.

## `allow_unsupported_sites` (type: `boolean`):

Try any site, not only the 725 with a dedicated extractor, by reading the schema.org recipe markup on the page. Turn this off to skip unknown sites instead.

## `max_concurrency` (type: `integer`):

Higher is faster but more likely to be rate-limited. Drop to 1–2 if you see failures.

## `proxy_country` (type: `string`):

Comma-separated 2-letter codes, rotated across retries. Residential proxies are recommended — many recipe sites block datacentre IPs.

## Actor input object example

```json
{
  "recipe_urls": [
    "https://www.allrecipes.com/recipe/20144/banana-banana-bread/"
  ],
  "max_recipes": 100,
  "allow_unsupported_sites": true,
  "max_concurrency": 5,
  "proxy_country": "US,GB,DE,NL,FR"
}
```

# Actor output Schema

## `dataset` (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 = {
    "recipe_urls": [
        "https://www.allrecipes.com/recipe/20144/banana-banana-bread/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mina_safwat/recipe-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 = { "recipe_urls": ["https://www.allrecipes.com/recipe/20144/banana-banana-bread/"] }

# Run the Actor and wait for it to finish
run = client.actor("mina_safwat/recipe-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 '{
  "recipe_urls": [
    "https://www.allrecipes.com/recipe/20144/banana-banana-bread/"
  ]
}' |
apify call mina_safwat/recipe-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mina_safwat/recipe-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/Sp3kBbJ2sZinL2bfW/builds/Mcfb9VNamhEc6qN7N/openapi.json
