# Store Locator Page Extractor (`junipr/store-locator-page-extractor`) Actor

Extract store-locator result entries, branch URLs, address blocks, phone numbers, hours, and pagination/API evidence from public locator pages

- **URL**: https://apify.com/junipr/store-locator-page-extractor.md
- **Developed by:** [junipr](https://apify.com/junipr) (community)
- **Categories:** SEO tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $27.50 / 1,000 locator page rendereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#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

## Store Locator Page Extractor

Turn public store-locator pages into capped branch records with extraction provenance and locator coverage diagnostics.

### What it does

- Extracts visible location, store, branch, and locator-result cards.
- Normalizes LocalBusiness, Store, Restaurant, Place, and Organization JSON-LD.
- Captures branch URL, address, phone, hours, distance, result position, and page position.
- Detects visible locator API endpoint strings when present in page markup.
- Deduplicates records and applies optional city or ZIP text filters.

### Input

- `startUrls`, `locatorUrls`, `sitemapUrls`, or `htmlInputs`.
- `searchLocations` and `searchRadiusMiles` for supplied locator evidence.
- `maxLocations`, `maxResultsPerQuery`, and `maxLocatorQueries`.
- `paginationLimit`, `maxBrowserPages`, `maxPages`, and `maxDepth`.
- `maxChargeUsd` for an estimated PPE spend ceiling.

### Important behavior

The extractor processes returned HTML and embedded structured data. If a locator requires a JavaScript form, provide the rendered result HTML or a permitted public locator response. Setting `interactWithSearchForm` without rendered results produces an explicit diagnostic.

### Dataset output

Each dataset item is one JSON object. The schema includes:

- locator and branch URLs.
- location name, address, phone, and hours.
- distance and result position.
- pagination page.
- observed endpoint evidence.
- extraction method.

The actor also writes a Markdown summary, CSV records, JSON issues, evidence excerpts, and run metadata to key-value storage. Raw HTML is excluded unless `includeRawSnapshots` is enabled.

### Pricing and charge safety

This actor uses pay per event with Apify platform-usage pass-through disabled. Charges are accepted before paid dataset or report output. `maxChargeUsd` stops the run before the next event would exceed the configured amount, including when the limit is zero.

| Event | Price |
| --- | ---: |
| `actor-start` | $0.08000 |
| `locator-page-rendered` | $0.02750 |
| `locator-result-record-extracted` | $0.00950 |
| `locator-issue-detected` | $0.01950 |
| `report-generated` | $0.18000 |

### Example input

```json
{
  "htmlInputs": [
    {
      "sourceUrl": "https://example.com/locations",
      "html": "<article class=\"location-card\"><h2>Downtown Branch</h2><p>100 Broadway, Nashville, TN 37201</p><p>615-555-0100</p><p class=\"hours\">Mon–Fri 8–6</p><a href=\"/locations/downtown\">Details</a></article>"
    }
  ],
  "maxPages": 1,
  "maxLocations": 10,
  "maxResultsPerQuery": 10,
  "interactWithSearchForm": false,
  "maxChargeUsd": 50
}
```

### Result quality

- Public URL fetching rejects localhost and private IPv4 targets.
- Domain allowlists, timeouts, request delays, crawl depth, and actor-specific limits are enforced.
- Missing or blocked source evidence produces an explicit diagnostic instead of invented values.
- Every dataset row follows the declared dataset schema.
- Reports include the evidence reference and recommended next action for each finding.

### Responsible use

Only process public pages or content you are authorized to analyze. Respect site terms, robots policies, rate limits, privacy obligations, and applicable law.

# Actor input Schema

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

Public pages to fetch when HTML snapshots are not supplied.

## `sitemapUrls` (type: `array`):

Optional public XML sitemaps used for same-domain discovery.

## `htmlInputs` (type: `array`):

Optional source-backed HTML snapshots for deterministic extraction.

## `allowedDomains` (type: `array`):

Optional domain allowlist applied to every fetched or discovered URL.

## `maxPages` (type: `integer`):

Maximum public pages fetched or analyzed.

## `maxDepth` (type: `integer`):

Same-domain internal-link discovery depth.

## `includeEvidence` (type: `boolean`):

Include source excerpts in dataset rows.

## `includeRawSnapshots` (type: `boolean`):

Write capped raw HTML snapshots to key-value storage.

## `requestDelayMs` (type: `integer`):

Delay between public HTTP requests in milliseconds.

## `timeoutMs` (type: `integer`):

Per-request timeout in milliseconds.

## `userAgentMode` (type: `string`):

HTTP user-agent profile.

## `locatorUrls` (type: `array`):

Additional public store-locator pages.

## `searchLocations` (type: `array`):

Optional city or ZIP text filters applied to extracted records.

## `searchRadiusMiles` (type: `number`):

Documented search radius associated with supplied locator evidence.

## `maxLocations` (type: `integer`):

Maximum extracted branch records per page and run cap.

## `interactWithSearchForm` (type: `boolean`):

When true without rendered results, emit a diagnostic requesting a rendered HTML or public API snapshot.

## `paginationLimit` (type: `integer`):

Maximum locator result pages supplied for analysis.

## `maxLocatorQueries` (type: `integer`):

Maximum supplied location filters used for a run.

## `maxResultsPerQuery` (type: `integer`):

Maximum branch records retained per locator query.

## `maxBrowserPages` (type: `integer`):

Hard cap on fetched or supplied locator pages.

## `maxChargeUsd` (type: `number`):

Maximum estimated PPE spend before a graceful stop.

## `includeReport` (type: `boolean`):

Write Markdown, CSV, JSON evidence, and run metadata.

## Actor input object example

```json
{
  "startUrls": [
    "https://example.com/"
  ],
  "sitemapUrls": [],
  "htmlInputs": [],
  "allowedDomains": [],
  "maxPages": 1,
  "maxDepth": 0,
  "includeEvidence": true,
  "includeRawSnapshots": false,
  "requestDelayMs": 250,
  "timeoutMs": 15000,
  "userAgentMode": "standard",
  "locatorUrls": [],
  "searchLocations": [],
  "searchRadiusMiles": 25,
  "maxLocations": 25,
  "interactWithSearchForm": false,
  "paginationLimit": 1,
  "maxLocatorQueries": 1,
  "maxResultsPerQuery": 25,
  "maxBrowserPages": 1,
  "maxChargeUsd": 50,
  "includeReport": true
}
```

# Actor output Schema

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

No description

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

// Run the Actor and wait for it to finish
const run = await client.actor("junipr/store-locator-page-extractor").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("junipr/store-locator-page-extractor").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 junipr/store-locator-page-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,junipr/store-locator-page-extractor"
        }
    }
}

```

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/F4RXzyplp3euiyzYR/builds/WNUP0HOtpxE4ULn2G/openapi.json
