Restaurant/Menu/Local Competitor Snapshot avatar

Restaurant/Menu/Local Competitor Snapshot

Pricing

Pay per usage

Go to Apify Store
Restaurant/Menu/Local Competitor Snapshot

Restaurant/Menu/Local Competitor Snapshot

Collects public restaurant website, menu, contact, and competitor-positioning signals into flat dataset rows.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Brian Keefe

Brian Keefe

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

11 days ago

Last modified

Share

restaurant-menu-local-competitor-snapshot

Production-oriented Apify Actor repo for collecting restaurant website, menu, and local competitor positioning signals from public web data.

What It Does

  • Accepts restaurantUrls, domains, and/or richer businessRows.
  • Fetches public restaurant pages without browser automation.
  • Extracts restaurant-level fields from HTML and schema.org JSON-LD.
  • Discovers menu pages, menu links, reservation links, delivery links, social links, and contact links.
  • Emits flat dataset rows:
    • one restaurant row per restaurant
    • optional menu_item rows per menu item
  • Stores the same array in dataset output and the OUTPUT key.
  • Gracefully degrades on fetch failures by emitting partial records with warnings instead of crashing the batch.

Public-Data Limitations

  • This actor uses only public website data.
  • It does not log in, use private APIs, or bypass access controls.
  • It avoids deep scraping of delivery platforms. Public outbound links are captured, but third-party menu ecosystems are not recursively scraped.
  • PDF and image menu links are recorded, but binary files are not parsed unless menu text is directly present in HTML.

Input

{
"restaurantUrls": ["https://example-restaurant.com"],
"domains": ["example-restaurant.com"],
"businessRows": [
{
"name": "Example Restaurant",
"url": "https://example-restaurant.com",
"domain": "example-restaurant.com",
"city": "Portland",
"state": "OR",
"fixtureId": "optional-fixture-id"
}
],
"maxPagesPerRestaurant": 3,
"includeMenuItems": true,
"fixtureMode": false
}

Output

The actor pushes flat-ish JSON rows to the default dataset and writes the same array to OUTPUT.

Restaurant row fields include:

  • recordType
  • restaurantKey
  • name
  • website
  • domain
  • status
  • warnings
  • cuisineTags
  • priceRange
  • ratingValue
  • reviewCount
  • telephone
  • email
  • address
  • reservationLinks
  • deliveryLinks
  • socialLinks
  • contactLinks
  • menuPageUrls
  • pdfOrImageMenuLinks
  • competitorPositioningFlags

Menu item rows include:

  • recordType: "menu_item"
  • restaurantKey
  • restaurantName
  • sourceUrl
  • itemName
  • itemDescription
  • itemPrice

See examples/sample-output.json for the deterministic fixture output.

Local Usage

Install dependencies:

$npm install

Run locally with Apify local storage:

$APIFY_LOCAL_STORAGE_DIR=./storage CRAWLEE_STORAGE_DIR=./storage node src/main.js

To use the deterministic fixture instead of live fetches, point INPUT at examples/sample-input.json or set fixtureMode: true in your input.

Smoke Tests

Run deterministic smoke tests:

$npm test

The smoke suite verifies:

  • exact fixture output from runSnapshot(input)
  • actor main path reading INPUT from Apify local storage
  • dataset write behavior
  • OUTPUT key write behavior

Project Structure

.actor/
examples/
src/
tests/smoke/

Main modules:

  • src/main.js
  • src/runner.js
  • src/input.js
  • src/extract.js
  • src/fetch.js

Publish

$apify push