# US Vet Clinic Scraper v2 (`therealmsc/us-vet-clinic-scraper`) Actor

Scrapes veterinary clinic data for any US state. Discovers clinics via DuckDuckGo search, crawls each website, extracts structured data. Zero API keys required.

- **URL**: https://apify.com/therealmsc/us-vet-clinic-scraper.md
- **Developed by:** [Matt Curtis](https://apify.com/therealmsc) (community)
- **Categories:** Lead generation, E-commerce, Open source
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## US Vet Clinic Scraper v2

Scrapes veterinary clinic data for any US state. Two-phase pipeline: DuckDuckGo discovery → Playwright website crawl. Zero API keys required.

### How It Works

**Phase 1 — Discovery:** Searches DuckDuckGo for each city in the selected state (3 queries per city: "veterinary clinic", "animal hospital", "veterinarian"). Deduplicates by domain and filters out directories, aggregators, and social media. Embedded city database covers 10,444 cities across all 50 US states + DC.

**Phase 2 — Crawl:** Visits each discovered clinic website with headless Chromium (Playwright). Extracts structured data using BeautifulSoup + regex patterns. Handles timeouts, retries, Cloudflare challenges, and dead sites gracefully.

### Input

| Field | Type | Description | Default |
|---|---|---|---|
| `state` | select | US state to scrape | Missouri |
| `maxCities` | integer | Limit cities (0 = all) | 0 |
| `maxClinicsPerCity` | integer | Max clinics per city (1–50) | 15 |

**Tip:** Use `maxCities: 2-3` for testing before running a full state.

### Output

Each run produces a dataset with one row per clinic:

| Field | Type | Description |
|---|---|---|
| `name` | string | Clinic name |
| `phone` | string | Phone number |
| `url` | string | Website URL |
| `city` | string | City |
| `state` | string | State |
| `address` | string | Street address (best-effort) |
| `founded` | string | Founding year, if found |
| `sat_hours` | string | Saturday hours, if found |
| `vets` | integer | Number of vets detected |
| `vet_names` | string | Vet names (comma-separated) |
| `aaha` | boolean | AAHA accredited |
| `exotics` | boolean | Treats exotic pets |
| `boarding` | boolean | Offers boarding |
| `grooming` | boolean | Offers grooming |
| `daycare` | boolean | Offers daycare |
| `urgent_care` | boolean | Emergency/urgent care |
| `online_pharmacy` | boolean | Online pharmacy available |

#### Sample Output

```json
{
  "name": "Western Sussex Animal Hospital",
  "phone": "302-337-7387",
  "url": "https://westernsussexvet.com/",
  "city": "Bridgeville",
  "state": "Delaware",
  "address": "16487 Sussex Hwy, Bridgeville, DE 19933",
  "founded": "",
  "sat_hours": "",
  "vets": 0,
  "vet_names": "",
  "aaha": false,
  "exotics": false,
  "boarding": false,
  "grooming": false,
  "daycare": false,
  "urgent_care": false,
  "online_pharmacy": false
}
````

### Limitations

- **Address extraction is best-effort.** Many vet sites use images or embedded Google Maps that aren't reliably scrapable. Phone + URL are the most reliable fields.
- **Coverage varies by area.** Rural areas with few clinics and limited web presence will return fewer results than urban areas.
- **DuckDuckGo search results may include out-of-state matches** for cities with common names (e.g., "Camden" appears in multiple states).
- **Not all websites respond.** Expect ~60–80% success rate on website crawls depending on site quality. Dead sites, heavy JavaScript, and aggressive bot protection will fail gracefully.

### Running

1. Select a **State** from the dropdown
2. Optionally set **Max Cities** to limit scope
3. Click **Start**

Runs typically take 2–10 minutes for small tests and 30–90 minutes for full states (depending on city count).

### Pricing

This Actor is free to run. You only pay for Apify platform usage (compute units based on runtime).

### Source

Built with Crawlee + Playwright + BeautifulSoup. City database compiled from US Census data.

### Support

For issues or feature requests, open an issue on [GitHub](https://github.com/therealmsc/vet-clinic-scraper).

# Actor input Schema

## `state` (type: `string`):

State name to scrape (e.g. 'Missouri', 'Nebraska', 'Kansas')

## `maxCities` (type: `integer`):

Limit cities to scrape (0 = all cities). Useful for testing.

## `maxClinicsPerCity` (type: `integer`):

Maximum clinic websites to crawl per city

## Actor input object example

```json
{
  "state": "Missouri",
  "maxCities": 0,
  "maxClinicsPerCity": 15
}
```

# 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("therealmsc/us-vet-clinic-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("therealmsc/us-vet-clinic-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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 therealmsc/us-vet-clinic-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=therealmsc/us-vet-clinic-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "US Vet Clinic Scraper v2",
        "description": "Scrapes veterinary clinic data for any US state. Discovers clinics via DuckDuckGo search, crawls each website, extracts structured data. Zero API keys required.",
        "version": "2.0",
        "x-build-id": "nrPm96JmazpGwhsga"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/therealmsc~us-vet-clinic-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-therealmsc-us-vet-clinic-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/therealmsc~us-vet-clinic-scraper/runs": {
            "post": {
                "operationId": "runs-sync-therealmsc-us-vet-clinic-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/therealmsc~us-vet-clinic-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-therealmsc-us-vet-clinic-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "state"
                ],
                "properties": {
                    "state": {
                        "title": "State",
                        "enum": [
                            "Alabama",
                            "Alaska",
                            "Arizona",
                            "Arkansas",
                            "California",
                            "Colorado",
                            "Connecticut",
                            "Delaware",
                            "District of Columbia",
                            "Florida",
                            "Georgia",
                            "Hawaii",
                            "Idaho",
                            "Illinois",
                            "Indiana",
                            "Iowa",
                            "Kansas",
                            "Kentucky",
                            "Louisiana",
                            "Maine",
                            "Maryland",
                            "Massachusetts",
                            "Michigan",
                            "Minnesota",
                            "Mississippi",
                            "Missouri",
                            "Montana",
                            "Nebraska",
                            "Nevada",
                            "New Hampshire",
                            "New Jersey",
                            "New Mexico",
                            "New York",
                            "North Carolina",
                            "North Dakota",
                            "Ohio",
                            "Oklahoma",
                            "Oregon",
                            "Pennsylvania",
                            "Rhode Island",
                            "South Carolina",
                            "South Dakota",
                            "Tennessee",
                            "Texas",
                            "Utah",
                            "Vermont",
                            "Virginia",
                            "Washington",
                            "West Virginia",
                            "Wisconsin",
                            "Wyoming"
                        ],
                        "type": "string",
                        "description": "State name to scrape (e.g. 'Missouri', 'Nebraska', 'Kansas')",
                        "default": "Missouri"
                    },
                    "maxCities": {
                        "title": "Max Cities",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Limit cities to scrape (0 = all cities). Useful for testing.",
                        "default": 0
                    },
                    "maxClinicsPerCity": {
                        "title": "Max Clinics Per City",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum clinic websites to crawl per city",
                        "default": 15
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
