# Yelp Business Scraper (`lmbtechnology/yelp-business-scraper`) Actor

Scrape Yelp businesses by search term and location, or from Yelp links: name, rating, reviews, price, categories, full address, coordinates, phone, website, hours, claimed status, photo count and amenities. Gets past Yelp's 240-result limit by splitting the map. Pay per business.

- **URL**: https://apify.com/lmbtechnology/yelp-business-scraper.md
- **Developed by:** [LMB Technology](https://apify.com/lmbtechnology) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 businesses

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

## Yelp Business Scraper

Turn any Yelp search into a clean list of businesses: name, phone, website, full address, map position, rating, review count, price, categories, opening hours, claimed status, photo count and amenities. Type what you look for (`plumbers`, `pizza`, `dentists`) and where (`Fort Myers, FL`), or paste Yelp links. No Yelp account and no Yelp API key.

Built for **lead generation and market research**: build call lists of local businesses, find unclaimed Yelp pages, compare competitors in a city, or map every coffee shop in a metro area. Yelp shows at most 240 results per search; this scraper can **split a search into smaller map areas** to collect thousands of businesses from one city, without duplicates.

### What you get

For every business (one row each):

- **Basics**: name, Yelp ID, Yelp URL, rating, review count, price level, categories (names and ids), a short review quote from the search page.
- **Contact and address** (with details, on by default): phone, website, street, city, state, ZIP code, country, full address, neighborhoods, service areas for businesses that come to you.
- **Map and hours**: latitude and longitude, opening hours for each day of the current week, time zone, open-now flag.
- **Profile** (with details): claimed or not, permanently closed or not, number of photos, main photo, amenities ("Offers delivery", "Wheelchair accessible", "Accepts Zelle", "Free Wi-Fi", "Parking: lot"...), specialties text, year established, licenses checked by Yelp, Yelp Guaranteed badge.
- **Where it came from**: search term, location, rank in Yelp's results, the search link.
- **Optional review highlights**: the short quoted phrases Yelp shows on business pages, with how many reviews mention them.

Errors (a location Yelp does not know, a business link that no longer exists) come out as separate `error` rows that are **not charged**, and the rest of the run continues.

### What it does not do

- **Full review texts.** You get the review quote from the search list and, if you want, Yelp's review highlights. For complete reviews use a dedicated Yelp reviews scraper.
- **More than 240 results per search without splitting.** That limit is Yelp's. Turn on "Split large searches" to go past it. A split search returns businesses in map order, not in Yelp's ranking.
- **Phone and website without details.** The search list only has name, rating, reviews, price, categories, street, city, coordinates and hours. Phone, website, state and ZIP code come from each business's details (the `business-details` event).
- **Emails or owner names.** Yelp does not publish them.
- **Logging in, posting or messaging businesses.** The scraper only reads public pages.
- **History.** Hours are this week's (including holiday hours), ratings and counts are as of the run.

Yelp changes its website from time to time. The scraper is tested every day; if Yelp blocks or changes something, runs report clear error rows instead of silently returning nothing, and fixes are published quickly.

### Input

| Field | Default | Meaning |
|---|---|---|
| `searchTerms` | | What to search for, one per line (`plumbers`, `pizza`). Leave empty to list everything in the locations. |
| `locations` | | Where: `City, ST`, a neighborhood with its city, or a ZIP code. Every term is searched in every location. |
| `startUrls` | | Yelp search links (filters in the link are kept) and business links. Any Yelp country site. |
| `maxResultsPerSearch` | 100 | Businesses per search term + location (or per search link). |
| `includeDetails` | true | Open each business page for phone, website, ZIP, claimed status and the rest. |
| `splitLargeSearches` | false | Go past Yelp's 240-result limit by splitting the map. |
| `category` | | Yelp category alias, e.g. `plumbing`, `italian`, `dentists`. |
| `priceLevels` | all | Keep only `1` to `4` ($ to $$$$). |
| `minRating` | any | Keep only 3, 3.5, 4 or 4.5 stars and up. |
| `openNow` | false | Keep only businesses open at the time of the run, in their own time zone. |
| `sortBy` | recommended | `recommended`, `rating` (highest rated) or `review_count` (most reviewed). |
| `includeReviewHighlights` | false | Add Yelp's review highlights (needs details, no extra charge). |
| `deduplicateAcrossSearches` | true | Save each business once per run even if several searches find it. |
| `maxConcurrency` | 10 | Pages loaded at the same time. |
| `proxyConfiguration` | Apify datacenter proxy | With the default, the run switches to residential proxies by itself if Yelp starts rate-limiting the datacenter IPs. |

Filters apply to searches. Business links are always saved as they are.

#### Example: a call list of plumbers

```json
{
  "searchTerms": ["plumbers", "water heater repair"],
  "locations": ["Fort Myers, FL", "Cape Coral, FL", "Naples, FL"],
  "maxResultsPerSearch": 100
}
```

Businesses found by two searches are saved once (see `deduplicateAcrossSearches`).

#### Example: every pizza place in a city

```json
{
  "searchTerms": ["pizza"],
  "locations": ["Austin, TX"],
  "maxResultsPerSearch": 2000,
  "splitLargeSearches": true,
  "includeDetails": false
}
```

Without details this is the cheapest way to map a market: name, rating, reviews, price, categories, street, city, coordinates and hours for each place.

#### Example: well-rated restaurants open right now

```json
{
  "searchTerms": ["restaurants"],
  "locations": ["Mission District, San Francisco, CA"],
  "openNow": true,
  "minRating": "4",
  "priceLevels": ["1", "2"],
  "maxResultsPerSearch": 50
}
```

#### Example: from Yelp links

```json
{
  "startUrls": [
    { "url": "https://www.yelp.com/search?find_desc=dentists&find_loc=Denver%2C+CO&sortby=review_count" },
    { "url": "https://www.yelp.com/biz/pedrosos-pizza-austin-6" }
  ],
  "maxResultsPerSearch": 50
}
```

### Output example

```json
{
  "type": "business",
  "yelpId": "_Y5GEb-PJvogHYUYuVJtmw",
  "name": "Pedroso's Pizza",
  "url": "https://www.yelp.com/biz/pedrosos-pizza-austin-6",
  "rating": 4.7,
  "reviewCount": 301,
  "price": "$$",
  "categories": ["Pizza"],
  "categoryAliases": ["pizza"],
  "phone": "(737) 600-1107",
  "website": "https://www.pedrosospizza.com",
  "address": "2207 Justin Ln, Ste D",
  "city": "Austin",
  "state": "TX",
  "postalCode": "78757",
  "country": "US",
  "fullAddress": "2207 Justin Ln, Ste D, Austin, TX 78757, United States",
  "neighborhoods": ["Allandale", "Brentwood"],
  "latitude": 30.344536,
  "longitude": -97.736291,
  "hours": { "Mon": "11:00 AM - 10:00 PM", "Tue": "11:00 AM - 10:00 PM", "Wed": "11:00 AM - 10:00 PM", "Thu": "11:00 AM - 10:00 PM", "Fri": "11:00 AM - 11:00 PM", "Sat": "11:00 AM - 11:00 PM", "Sun": "11:00 AM - 10:00 PM" },
  "timezone": "America/Chicago",
  "isOpenNow": true,
  "isClaimed": true,
  "isClosed": false,
  "photosCount": 448,
  "photoUrl": "https://s3-media0.fl.yelpcdn.com/bphoto/p6VvfynGK2WdGOL6GKeAsg/o.jpg",
  "amenities": ["Offers delivery", "Offers take-out", "Wheelchair accessible", "Outdoor seating"],
  "specialties": "Slice Shop and take out spot serving N.Y style, Grandma, Sicilian and Classic American Pies.",
  "yearEstablished": null,
  "menuUrl": null,
  "serviceArea": null,
  "licenses": [],
  "isYelpGuaranteed": false,
  "reviewSnippet": "This by far is the BEST pizza place in Austin...",
  "searchTerm": "pizza",
  "searchLocation": "Austin, TX",
  "searchUrl": "https://www.yelp.com/search?find_desc=pizza&find_loc=Austin%2C+TX",
  "rank": 1,
  "mapArea": null,
  "alias": "pedrosos-pizza-austin-6",
  "detailsScraped": true,
  "scrapedAt": "2026-10-21T03:42:34.246Z"
}
```

Download the results as JSON, CSV, Excel or HTML from the run's **Output** tab. The dataset has three table views: **Overview** (contact details), **Map and hours** and **Profile**. The `RUN-SUMMARY` record in the key-value store shows, per search, how many results Yelp has, how many were saved and any error.

### Pricing

You pay per result, not for compute time or proxies:

| Event | When | Price |
|---|---|---|
| Business | Each business saved | see the Pricing tab |
| Business detail | Each business saved with details (`includeDetails`, and business links) | see the Pricing tab |
| Actor start | Once per run | Apify's standard small start fee |

Error rows are free. Filtered-out businesses (rating, open now) are free. Duplicates removed by `deduplicateAcrossSearches` are free. If the details of a business cannot be loaded, the business is saved with its search data, a `detailsError` note, and only the business event is charged.

Set **Maximum cost per run** in the run options to cap spending: the scraper stops cleanly when it is reached and keeps everything already saved.

### Tips

- **Always add the state** to locations (`Springfield, IL`, not `Springfield`).
- For lead lists, keep **details on**: phone and website only come from business pages.
- `isClaimed: false` marks businesses that have not claimed their Yelp page, a common target for marketing agencies.
- For a whole city, use **Split large searches** with a high maximum and details off first; then run the business links you care about with details.
- Use the `yelpId` to merge results from several runs.
- The same business can show up with a different rank in another search; ranks are per search.

### Is it legal to scrape Yelp?

This scraper collects public business information that Yelp shows to every visitor without logging in. It does not collect personal data about reviewers. Yelp's terms of service do not allow automated access, and laws differ by country, so check your use case (and talk to a lawyer when in doubt) before using the data, especially for outreach, and follow the rules for cold calls and emails where you live. This scraper is not affiliated with, endorsed by or connected to Yelp.

### Support

Found a problem or need a field? Open an issue on the **Issues** tab with the run link and the input you used. Issues are answered within a few days.

# Changelog

This Actor's version history is a separate document: https://apify.com/lmbtechnology/yelp-business-scraper/changelog.md

# Actor input Schema

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

What to search for, one per line, as you would type it on Yelp: `plumbers`, `pizza`, `dentists`, `hair salons`. Every search term is run in every location. Leave empty to list all businesses in the locations.

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

Where to search, one per line: `City, ST` (`Fort Myers, FL`), a neighborhood with its city (`Mission District, San Francisco, CA`) or a ZIP code (`33901`). Always add the state: a bare city name can match a place in another country.

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

Optional. Yelp search links (`https://www.yelp.com/search?find_desc=...&find_loc=...`, filters in the link are kept) and business links (`https://www.yelp.com/biz/...`). Links from any Yelp country site work. Business links always include details.

## `maxResultsPerSearch` (type: `integer`):

How many businesses to save for each search term + location (and each search link), in Yelp's order. Yelp itself never lists more than 240 for one search; turn on "Split large searches" to go past that.

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

Open each business page to add phone, website, state, ZIP code, claimed status, photo count, amenities, specialties, year established and service areas. Recommended for lead lists. Costs one extra `business-details` event per business. When off you get what the search list shows: name, rating, reviews, price, categories, street and city, coordinates and hours.

## `splitLargeSearches` (type: `boolean`):

When a search hits Yelp's 240-result limit, split its map area into four smaller areas, again and again, until every area has fewer than 240 results. Duplicates are removed. Use it with a higher "Maximum businesses per search" (for example 2,000) to collect a whole city. Results are then in map order, not Yelp's ranking.

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

Optional Yelp category alias, the `cflt` value in Yelp links: `plumbing`, `italian`, `dentists`, `hair`, `autorepair`. Leave empty for no filter.

## `priceLevels` (type: `array`):

Keep only these Yelp price levels. Leave empty for all prices. Businesses without a price level (most services) are left out by Yelp when this is set.

## `minRating` (type: `string`):

Keep only businesses with at least this star rating. Businesses without reviews are left out when this is set.

## `openNow` (type: `boolean`):

Keep only businesses that are open at the time of the run, in their own time zone (checked against Yelp's filter and each business's hours).

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

Yelp's sort order for the searches. With "Maximum businesses per search" below 240 this decides which businesses you get.

## `includeReviewHighlights` (type: `boolean`):

Add Yelp's review highlights (short quoted phrases with how many reviews mention them). Needs "Include details". These are not full reviews. No extra charge, a little slower.

## `deduplicateAcrossSearches` (type: `boolean`):

Save each business only once per run, even when several search terms or locations find it (you pay for it once). Turn off to get the business again for every search that finds it.

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

How many Yelp pages to load at the same time. Lower it if you see many retries in the log.

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

Apify Proxy. Datacenter proxies (the default) work for Yelp; if Yelp starts rate-limiting them the run switches to residential proxies by itself. Pick a proxy group yourself only if you need to.

## Actor input object example

```json
{
  "searchTerms": [
    "plumbers"
  ],
  "locations": [
    "Fort Myers, FL"
  ],
  "maxResultsPerSearch": 20,
  "includeDetails": true,
  "splitLargeSearches": false,
  "minRating": "0",
  "openNow": false,
  "sortBy": "recommended",
  "includeReviewHighlights": false,
  "deduplicateAcrossSearches": true,
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `businesses` (type: `string`):

All items as JSON (type "business" or "error").

## `overviewCsv` (type: `string`):

Name, rating, contact details and address as CSV.

## `runSummary` (type: `string`):

Per search: results Yelp shows, businesses saved, pages loaded, map areas and errors.

# 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": [
        "plumbers"
    ],
    "locations": [
        "Fort Myers, FL"
    ],
    "maxResultsPerSearch": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lmbtechnology/yelp-business-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": ["plumbers"],
    "locations": ["Fort Myers, FL"],
    "maxResultsPerSearch": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("lmbtechnology/yelp-business-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": [
    "plumbers"
  ],
  "locations": [
    "Fort Myers, FL"
  ],
  "maxResultsPerSearch": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call lmbtechnology/yelp-business-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lmbtechnology/yelp-business-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/Gbofy9Ctcmvns8q6R/builds/9vTep7oCdHG5vaEmi/openapi.json
