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

An Apify actor that extracts business listings from Yelp based on search terms and locations with comprehensive structured data including contact information, ratings, and reviews.

- **URL**: https://apify.com/happitap/yelp-business-scraper.md
- **Developed by:** [HappiTap](https://apify.com/happitap) (community)
- **Categories:** Lead generation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## 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

## Yelp Business Scraper

An Apify actor that extracts business listings from Yelp based on search terms and locations with comprehensive structured data including contact information, ratings, and reviews.

### What It Does

This scraper extracts structured data from Yelp search results including:

| Field | Description |
|-------|-------------|
| `name` | Business name |
| `phone` | Business phone number |
| `website` | Business website URL |
| `rating` | Average Yelp rating (e.g., 4.5) |
| `reviews` | Total number of Yelp reviews |
| `address` | Business address |
| `sourceUrl` | Yelp page URL for this business |

### Supported Search Types

- **Business Types**: Any business category (e.g., 'dentist', 'restaurant', 'plumber')
- **Locations**: Cities, states, or specific areas (e.g., 'Los Angeles', 'New York, NY')
- **Combined Searches**: Business type + location combinations

### Use Cases

- **Lead Generation**: Find potential business leads in specific locations
- **Market Research**: Analyze business density and competition in areas
- **Contact Information**: Gather business contact details for outreach
- **Competitive Analysis**: Research competitors in specific markets
- **Local Business Discovery**: Find businesses in target locations

### Input

The actor accepts the following input format:

```json
{
  "searchTerm": "dentist",
  "location": "Los Angeles",
  "maxItems": 50
}
```

#### Input Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `searchTerm` | String | Yes | - | Business type or service to search for |
| `location` | String | Yes | - | City, state, or area to search in |
| `maxItems` | Number | No | `50` | Maximum number of businesses to extract |

#### Example Search Terms

**Business Types:**

- `dentist`
- `restaurant`
- `plumber`
- `lawyer`
- `gym`
- `salon`

**Locations:**

- `Los Angeles`
- `New York, NY`
- `San Francisco`
- `Chicago, IL`
- `Miami, FL`

### Output

The actor outputs structured data for each business found:

```json
{
  "name": "Dr. Sarah Johnson Dental Practice",
  "phone": "(555) 123-4567",
  "website": "https://www.drsarahjohnson.com",
  "rating": 4.8,
  "reviews": 127,
  "address": "123 Main St, Los Angeles, CA 90210",
  "sourceUrl": "https://www.yelp.com/biz/dr-sarah-johnson-dental-practice-los-angeles",
  "scrapedAt": "2024-01-01T00:00:00.000Z"
}
```

### Example Usage

#### Search for Dentists in Los Angeles

```json
{
  "searchTerm": "dentist",
  "location": "Los Angeles",
  "maxItems": 50
}
```

#### Search for Restaurants in New York

```json
{
  "searchTerm": "restaurant",
  "location": "New York, NY",
  "maxItems": 25
}
```

#### Search for Plumbers in San Francisco

```json
{
  "searchTerm": "plumber",
  "location": "San Francisco",
  "maxItems": 30
}
```

### How It Works

1. **URL Generation**: Constructs Yelp search URLs based on search term and location
2. **Page Navigation**: Navigates to Yelp search results pages
3. **Data Extraction**: Uses specialized selectors to extract business information
4. **Contact Details**: Extracts phone numbers, websites, and addresses
5. **Rating Analysis**: Captures Yelp ratings and review counts
6. **Data Validation**: Ensures only businesses with valid names and URLs are included
7. **Structured Output**: Returns clean, structured data ready for analysis

### Features

- **Flexible Search**: Support for any business type and location combination
- **Comprehensive Data**: Extracts all essential business information
- **Stealth Mode**: Uses Puppeteer with stealth plugins to avoid detection
- **Proxy Support**: Built-in proxy rotation for reliable scraping
- **Error Handling**: Graceful error handling with detailed logging
- **Data Validation**: Ensures data quality with validation checks
- **Contact Information**: Extracts phone numbers and website URLs
- **Rating Data**: Captures Yelp ratings and review counts

### Installation

1. Clone this repository
2. Install dependencies: `npm install`
3. Run the actor: `npm start`

### Development

- `npm start` - Run the actor
- `npm run format` - Format code with Prettier
- `npm run lint` - Run ESLint
- `npm run lint:fix` - Fix ESLint issues

### Architecture

- `src/main.js` - Main entry point and input validation
- `src/routes.js` - Request routing and page type detection
- `src/handlers/yelpSearchResults.js` - Yelp search results scraping logic
- `src/puppeteerLauncher.js` - Puppeteer browser configuration with stealth mode

### Notes

- The scraper is designed to be respectful of Yelp's servers and includes appropriate delays
- Results may vary based on Yelp's page structure changes
- The scraper automatically handles different Yelp page layouts
- All extracted data is timestamped for tracking purposes
- Website URLs are cleaned from Yelp redirect links when possible
- Phone numbers are extracted in various formats and cleaned for consistency

# Actor input Schema

## `searchTerm` (type: `string`):

Business type or service to search for (e.g., 'dentist', 'restaurant', 'plumber')

## `location` (type: `string`):

City, state, or area to search in (e.g., 'Los Angeles', 'New York, NY', 'San Francisco')

## `maxItems` (type: `integer`):

Maximum number of businesses to extract

## Actor input object example

```json
{
  "maxItems": 50
}
```

# Actor output Schema

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

Extracted data items stored in the default dataset.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("happitap/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 = {}

# Run the Actor and wait for it to finish
run = client.actor("happitap/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 '{}' |
apify call happitap/yelp-business-scraper --silent --output-dataset

```

## MCP server setup

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