A collection of browser automation implementations for extracting SHA256 hashes from OpenTable's GraphQL API. These hashes are required for making authenticated requests to OpenTable's restaurant availability endpoints.
This repository provides multiple working implementations for extracting SHA256 hashes that OpenTable uses for their persisted GraphQL queries. The extracted hashes can be used to make direct API calls to check restaurant availability without going through the web interface.
Primary use case: Automated restaurant availability checking and reservation monitoring.
- Multi-browser support: Works with both Puppeteer/Chromium and Playwright/Firefox
- Hash caching: Extracted hashes are cached for 1 hour to reduce requests
- Request interception: Captures GraphQL requests in real-time
- Anti-detection measures: Includes stealth techniques to avoid bot detection
- Comprehensive documentation: Full investigation of what works and what doesn't
opentable_playwright_firefox_sha_extractor.py- ✅ Playwright + Firefox (recommended)opentable_pyppeteer_sha_extractor.py- ✅ Puppeteer + Chromium (original working solution)
opentable_playwright_chromium_sha_extractor.py- ❌ Playwright + Chromium (blocked by OpenTable)
main.py- Example usage and testingtest_playwright_firefox.py- Test suite for Playwright implementationrequirements.txt- Python dependenciesREADME.md- This documentation
| Library | Browser | Status | Notes |
|---|---|---|---|
| Puppeteer | Chromium | ✅ Works | Original working implementation |
| Playwright | Firefox | ✅ Works | Alternative working implementation |
| Playwright | Chromium | ❌ Blocked | OpenTable specifically blocks Playwright's Chromium |
OpenTable has sophisticated anti-automation detection that specifically targets Playwright's Chromium implementation while allowing:
- Puppeteer + Chromium ✅ (works)
- Playwright + Firefox ✅ (works)
This suggests OpenTable can distinguish between different automation libraries at the browser fingerprinting level, not just user agents or launch arguments.
Multiple approaches were tested to make Playwright + Chromium work:
- Response events instead of request events - Failed
- Removed
--disable-http2flag - HTTP/2 protocol errors - Matched exact Firefox user agent - Still blocked
- Route interception - Still blocked
- Puppeteer-style launch arguments - Still blocked
- All anti-detection measures - Still blocked
Conclusion: OpenTable's detection is specifically targeting Playwright's Chromium implementation at a deeper level than typical bot detection.
- Uses
pyppeteer.launch()with Chromium - Chrome user agent:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 - Request interception via
setRequestInterception(True) - Launch args:
--disable-dev-shm-usage,--disable-web-security,--disable-features=VizDisplayCompositor
- Uses
playwright.firefox.launch() - Firefox user agent:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/121.0 - Request interception via
page.on('request') - Launch args:
--no-sandbox,--disable-setuid-sandbox,--disable-http2
from opentable_playwright_firefox_sha_extractor import get_playwright_firefox_sha_extractor
extractor = get_playwright_firefox_sha_extractor()
sha_hash = await extractor.get_sha256_hash()
print(f"SHA256: {sha_hash}")from opentable_playwright_chromium_sha_extractor import get_playwright_chromium_sha_extractor
# NOTE: This will fail due to OpenTable blocking Chromium
extractor = get_playwright_chromium_sha_extractor()
sha_hash = await extractor.get_sha256_hash() # Returns NoneThe Firefox implementation successfully extracts the SHA256 hash for RestaurantsAvailability:
c056cbf4dbe6a95dbb5f814916415dcff0b2c93c180a456d0d4a3a3f38d0b2cc
The Chromium implementation fails due to OpenTable blocking Chromium browsers.
pip install -r requirements.txt
playwright install firefox# Test Playwright Firefox implementation
python test_playwright.py
# Test pyppeteer implementation (may have dependency issues)
python test_pyppeteer.py