🎉 Premium Proxies · 24-Hour Free TrialClaim Now
Guides

How to Scrape OpenTable Data (Availability and Reviews)

Scrape OpenTable data that survives the next deploy: read ratings and reviews from each restaurant's JSON-LD, then pull availability from the GraphQL API.

S SparkProxy 0 23 min read
Share
How to Scrape OpenTable Data (Availability and Reviews)

To scrape OpenTable data that survives OpenTable's next deploy, split the job into two problems that behave nothing alike: the static facts and the live availability. Ratings, review counts, cuisine, price band, and address all sit in a schema.org JSON-LD block on every restaurant page, so those parse cleanly and almost never move. Reservation time slots are the hard part. OpenTable loads them from a GraphQL endpoint (/dapi/fe/gql) guarded by a CSRF token and a persisted-query hash it rotates between releases, so they are not in the initial HTML at all. This guide walks the full pipeline for public OpenTable data: searching a metro, reading ratings from JSON-LD, pulling live availability the durable way, and paging through verified-diner reviews without tripping the bot wall. Every request runs through SparkProxy's Scraping API, so browser rendering and residential IP rotation are request parameters instead of infrastructure you babysit.

What data you can extract (fields reference)

An OpenTable restaurant page carries most of what you want inside one embedded JSON-LD block, plus availability that lives somewhere else entirely. The search results page is thinner: it is a list of cards linking to restaurant profiles, so the durable pattern is to harvest restaurant slugs from search, then follow each one for the full record. Here is the reference set worth pulling, with the stable way to get each field as of mid-2026.

FieldWhere it livesHow to get itNotes
Restaurant nameJSON-LD `name`; page `h1`Parse the `application/ld+json` blockJSON-LD is the most stable source
Restaurant slugcanonical URL `/r/``link[rel="canonical"]` or the `/r/` hrefYour stable per-restaurant identifier
RatingJSON-LD `aggregateRating.ratingValue`float, 1.0 to 5.0OpenTable rates on a 5-point scale
Review countJSON-LD `aggregateRating.reviewCount`integerMatches the "N reviews" on the page
CuisineJSON-LD `servesCuisine`e.g. "Italian", "Steakhouse"Sometimes a list
Price bandJSON-LD `priceRange``$` to `$$$$`OpenTable maps this to its own tiers
AddressJSON-LD `address` (PostalAddress)street, locality, region, postal codeCleanly split into fields
PhoneJSON-LD `telephone`formatted stringNot always present
Availability (time slots)GraphQL `/dapi/fe/gql`render the page, then read slot buttonsNOT in the JSON-LD or initial HTML
Reviews (sample)JSON-LD `review[]`first few reviewsFull set via `?page=` pagination

Two rows explain the whole shape of this job. The rating, review count, cuisine, price, and address are handed to you already parsed inside the