top of page

How to scrape restaurant data from Uber Eats using the Minexa API

Uber Eats city pages list every restaurant available for delivery in a given area, complete with ratings, cuisine types, delivery times, and promotional labels. That data is publicly visible but entirely unstructured. Pulling it manually is slow and does not scale. This guide shows how to extract it programmatically using the Minexa API.

What the data looks like

Before walking through the extraction steps, here is a sample of the structured output Minexa returns from an Uber Eats city listing page. Each row corresponds to one restaurant entry on the page.

[
  {
    "restaurant_name": "Burger King",
    "cuisine_category": "Burgers, Fast Food",
    "delivery_time": "20-30 min",
    "rating": "4.5",
    "promo_label": "Featured",
    "thumbnail_image": "https://tb.ueat.io/img/burger-king.jpg",
    "restaurant_link": "/store/burger-king-jackson/123456"
  },
  {
    "restaurant_name": "Waffle House",
    "cuisine_category": "Breakfast, American",
    "delivery_time": "25-35 min",
    "rating": "4.2",
    "promo_label": "",
    "thumbnail_image": "https://tb.ueat.io/img/waffle-house.jpg",
    "restaurant_link": "/store/waffle-house-jackson/789012"
  },
  {
    "restaurant_name": "Domino's Pizza",
    "cuisine_category": "Pizza, Italian",
    "delivery_time": "30-40 min",
    "rating": "4.3",
    "promo_label": "Sponsored",
    "thumbnail_image": "https://tb.ueat.io/img/dominos.jpg",
    "restaurant_link": "/store/dominos-jackson/345678"
  }
]

The restaurant_link field is particularly useful for pipeline work. It gives you a direct path to each restaurant detail page, where menu items, prices, and availability can be extracted in a second pass. The promo_label field distinguishes organic listings from featured or sponsored placements, which matters if you are tracking market positioning across cities.

Ready to build this yourself? Start by installing the Minexa Chrome extension and follow the steps below.

Video walkthrough

Watch the full extraction process before going through the step-by-step screenshots below.

Step-by-step extraction walkthrough

Open the Minexa dashboard and navigate to the Uber Eats city page you want to scrape. The starting URL used here is the Jackson, GA listing page.

Once the page has loaded, open the Minexa Chrome extension. You will see the extension popup with a confirmation button. Click I am on the right page to proceed.

Minexa then scans the page for pagination signals. It will show you what it detected and ask you to confirm before continuing. Review the detected pagination logic and click Continue.

Next, choose whether to scrape the listing only or the listing plus linked detail pages. For a restaurant directory pipeline, selecting list and their linked details gives you both the summary row and the full restaurant page in one pass.

Select your scraping mode. For most Uber Eats city pages, the simple scraping scenario works well. Advanced mode is available if you need custom click sequences or scroll behavior before data loads.

Minexa highlights the full restaurant listing container automatically. This is the parent HTML element wrapping all restaurant cards on the page. You do not need to click individual fields.

After confirming the container, Minexa creates the scraper and surfaces all identified data points. Use the next and previous navigation to review each extracted column before proceeding.

Click API Request in the top right to view the pre-generated Python code and the JSON request body. Copy the scraper ID shown here for use in your API calls.

Calling the Minexa API

Once your scraper is trained, call the Minexa API with your list of Uber Eats city page URLs. The request below uses scraper ID 6312 and requests the top 30 columns by relevance rank.

import requests

url = "https://api.minexa.ai/data/"
api_key = "YOUR_API_KEY"

data = {
  "batches": [
    {
      "scraper_id": 6312,
      "columns": ["top_30"],
      "urls": [
        "https://www.ubereats.com/city/jackson-ga",
        "https://www.ubereats.com/city/atlanta-ga"
      ],
      "scraping": {
        "js_render": True,
        "proxy": "verified"
      }
    }
  ],
  "threads": 5
}

headers = {
  "Content-Type": "application/json",
  "api-key": api_key
}

response = requests.post(url, json=data, headers=headers)
print(response.json())

The columns parameter accepts either a top_N shorthand or an explicit list of column names generated during scraper training. Both return the same fields and cost the same credits. For production pipelines where you need specific fields only, pass named columns to keep output schemas consistent across runs.

Because Uber Eats city pages are JavaScript-rendered, js_render: true is required. If you encounter low success rates on certain city pages, try switching to a stronger provider in the scraping settings. The extension shows prebuilt configurations you can copy directly into your request body.

Up to 50,000 URLs can be submitted in a single batch request, so covering hundreds of cities in one call is straightforward. For ongoing monitoring across many city URLs, set up your own cron job and pass fresh URL lists to the API on your preferred schedule.

The trained scraper ID stays stable indefinitely. Once you have it, every future extraction call requires only updating the URL list in the request body.

Recent Posts

See All

Comments


Heading 2

bottom of page