Grab Scraper - GrabFood Menus & GrabMart Data avatar

Grab Scraper - GrabFood Menus & GrabMart Data

Pricing

from $2.20 / 1,000 results

Go to Apify Store
Grab Scraper - GrabFood Menus & GrabMart Data

Grab Scraper - GrabFood Menus & GrabMart Data

Extract GrabFood restaurants, menus, and GrabMart products across eight Southeast Asian markets. Get merchant IDs, public URLs, ratings, and prices when available. Pay per delivered row plus a start fee.

Pricing

from $2.20 / 1,000 results

Rating

0.0

(0)

Developer

kane liu

kane liu

Maintained by Community

Actor stats

1

Bookmarked

77

Total users

39

Monthly active users

4.9 hours

Issues response

a day ago

Last modified

Security

Limited permissions

Share

Grab Scraper

Extract GrabFood restaurants, menus, and GrabMart listings across eight Southeast Asian markets as rows you can export.

  • Find merchants by keyword, cuisine, chain, delivery location, or public directory.
  • Collect menu items and product details with prices when available.
  • Keep merchant IDs and URLs for matching across runs.
  • Export rows or use them with AI agents and the Apify API.
  • Pay $3.00 per 1,000 rows on the Free plan, plus a small start fee.

What does Grab Scraper do?

Grab Scraper collects public data from food.grab.com and mart.grab.com. Supported market inputs are Singapore (sg), Malaysia (my), Philippines (ph), Thailand (th), Vietnam (vn), Indonesia (id), Cambodia (kh), and Myanmar (mm). Availability varies by location and mode.

  • Discovery: search, cuisine, recommended, chain, and discoverCategories find restaurants, branches, or categories.
  • Details: restaurant returns merchants and optional menu rows; mart_item returns one product's details.
  • GrabMart: mart finds merchants; mart_items and mart_merchants list public directory entries.
  • Directories and URLs: directory lists GrabFood merchants; startUrls accepts several supported links.
  • Optional rows: includeMenuItems, expandBranches, emitCuisines, and emitPromoLabels are off by default. Each extra row is billed at the same price and counts toward the input's limit.

What data can you extract from Grab?

Each row represents one entity. Fields vary by mode and source availability. rowType identifies the entity; itemType remains for compatibility.

Merchants: restaurant

Includes GrabFood restaurants, branches, GrabMart merchants, and directory entries.

FieldDescriptionExample
merchantIdGrab merchant identifier2-C2EYTY3AJ6NZKA
nameMerchant nameExample Kitchen
urlPublic merchant linkhttps://food.grab.com/ph/en/restaurant/example/2-C2EYTY3AJ6NZKA
businessTypeFood or grocery merchantFOOD
countryCodeMarket code in outputPH
ratingPublished rating4.6
deliveryFeePublished delivery fee29
etaDelivery estimate, when supplied30
cuisineCuisine tagsChicken,Pizza
addressPublic merchant address, when available{"full": null}
directoryOnlyDirectory entry without confirmed detailstrue
nameSourceOrigin of a directory nameurl_slug
detailStatusDirectory detail resultroute_shell
FieldDescriptionExample
itemIdMenu product identifier, when suppliedITEM001
nameProduct nameChicken rice
sectionMenu sectionRice meals
pricePublished list price120
currencyCurrency codePHP
restaurantNameParent restaurantExample Kitchen
restaurantCityRestaurant's address city, not delivery cityMakati

GrabMart directory products: martItem

FieldDescriptionExample
itemIdProduct identifierSGITE2023041907043919153
slugProduct URL textpokka-green-tea
urlPublic product linkhttps://mart.grab.com/sg/en/item/pokka-green-tea/SGITE2023041907043919153
lastmodSitemap publication date, not price-change time2026-10-01

GrabMart product details: mart_item_detail

FieldDescriptionExample
nameProduct nameGreen tea
descriptionPublished product descriptionBottled green tea
priceV2Structured list price{"amountInMinor": 250}
discountedPriceV2Structured discounted price{"amountInMinor": 220}
availableAvailability supplied by Grabtrue
barcodeProduct barcode, when suppliednull

Categories: category

FieldDescriptionExample
idCategory identifierpizza
nameCategory namePizza
urlCategory or restaurant-list linkhttps://food.grab.com/ph/en/cuisines/pizza

Promotions: promo

FieldDescriptionExample
merchantIdAssociated merchant2-C2EYTY3AJ6NZKA
namePublished promotion textDelivery offer

Labels: label

FieldDescriptionExample
merchantIdAssociated merchant2-C2EYTY3AJ6NZKA
namePublished label textPopular

Contact fields such as phones, emails, and web can be empty. leadAbsences explains missing information; 未验证 means unverified, not confirmed absent. The city field describes the requested delivery location, not necessarily the merchant's address.

How to scrape Grab

  1. Open Grab Scraper in Apify Console.
  2. Choose countryCode and fill a target such as keyword.
  3. Set maxResults to 3 for a small first run.
  4. Click Start and wait for completion.
  5. Open the dataset and download rows, or read them through the API.

Empty input starts a billed example search for pizza in ph, capped at 3 rows. With mode: "auto", one target selects its matching mode. When several targets are filled, priority is startUrls, restaurantUrl, merchantId, itemId, chainName, cuisineSlug, then keyword.

Use keyword for restaurant discovery. Explicit search without a keyword searches for pizza.

Restaurant

Use restaurantUrl or merchantId. Enable includeMenuItems for separate menu rows; the merchant row also counts.

GrabMart feed

Choose mart and optionally a grocery keyword. It returns merchants, not a complete product catalog.

GrabMart product directory

Choose mart_items for product IDs and URLs. Directory rows do not promise prices or availability.

GrabMart product detail

Choose mart_item with a complete product link in restaurantUrl, or itemId plus itemSlug. Preserve merchant information from the full link when present.

GrabMart merchant directory

Choose mart_merchants for published shop entries. Listing a shop does not prove current deliverability.

Chain

Fill chainName for branch listings and public addresses when supplied.

Cuisine

Fill cuisineSlug; optionally add cuisineId. Explicit cuisine can also use keyword as its slug.

Choose recommended for merchants around your delivery location. No keyword is required.

Start URLs

Fill startUrls with supported restaurant, cuisine, or GrabMart links. Restaurant links can include menu rows.

Discover categories

Choose discoverCategories for category shortcuts in the selected market. No target is required.

GrabFood directory

Choose directory and optionally sitemapCity. Names derived from URLs are marked nameSource: "url_slug". modifiedSince filters sitemap dates inclusively. enrichDetails checks up to maxEnrich pages; pages without merchant details remain directoryOnly: true.

What to fill in

FieldWhat to enterDefault
modeCollection mode, or automatic selectionauto
countryCodeOne supported market codeph
keywordOne search phraseEmpty; example pizza
startUrlsList of supported Grab linksEmpty
restaurantUrlRestaurant link; product link for mart_itemEmpty
merchantIdMerchant identifierEmpty
merchantSlugMerchant text from its URLEmpty
itemIdGrabMart product identifierEmpty
itemSlugProduct text from its URLEmpty
chainNameChain name or slugEmpty
cuisineSlugCuisine slugEmpty
cuisineIdOptional cuisine identifierEmpty
maxResultsRows per input, from 1 to 50070; form example 3
cityDelivery city slugMarket's main city
latlngDelivery pin; overrides cityEmpty
businessTypeALL, FOOD, or MART for search/recommendedALL
langLanguage path supported by the marketen
includeMenuItemsSeparate menu rows on restaurant pagesfalse
maxMenuItemsPerRestaurantMenu rows per restaurant25
expandBranchesAdditional branch merchant rowsfalse
emitCuisinesAdditional cuisine category rowsfalse
emitPromoLabelsAdditional promotion and label rowsfalse
pageSizeMerchants per page, from 1 to 3232
cursorPrevious RUN_SUMMARY.nextCursor objectEmpty
sitemapCityPublished sitemap city slugEmpty
sitemapShardZero-based sitemap file index0
sitemapOffsetZero-based entry offset0
sitemapMaxShardsMaximum sitemap files, from 1 to 51
modifiedSinceInclusive sitemap date, YYYY-MM-DDEmpty
enrichDetailsCheck directory merchant detailsfalse
maxEnrichDirectory detail pages to check5
useSeedPoolUse previously discovered URLs for detail modesfalse
seedCountPreviously discovered URLs to select3
seedFamilymart_items, mart_merchants, or food_merchantsMode-dependent
seedPoolMaxAgeMaximum age of saved URLs in seconds86400
persistSeenSkip previously delivered rows for the same queryfalse
proxyCountryOptional country hint for chain requestsMarket country

Search example

{"keyword": "pizza", "countryCode": "ph", "maxResults": 3}

Restaurant example

{"mode": "restaurant", "countryCode": "ph", "merchantId": "2-C2EYTY3AJ6NZKA", "includeMenuItems": true, "maxResults": 3}

GrabMart feed example

{"mode": "mart", "countryCode": "my", "city": "penang", "keyword": "grocery", "maxResults": 3}

GrabMart product directory example

{"mode": "mart_items", "countryCode": "sg", "sitemapCity": "singapore", "maxResults": 3}

GrabMart product detail example

{"mode": "mart_item", "countryCode": "sg", "itemId": "SGITE2023041907043919153", "itemSlug": "pokka-green-tea", "maxResults": 1}

GrabMart merchant directory example

{"mode": "mart_merchants", "countryCode": "sg", "sitemapCity": "singapore", "maxResults": 3}

Chain example

{"chainName": "mcdonalds", "countryCode": "id", "maxResults": 3}

Cuisine example

{"cuisineSlug": "pizza", "countryCode": "ph", "city": "cebu", "maxResults": 3}
{"mode": "recommended", "countryCode": "ph", "maxResults": 3}

Start URLs example

{"startUrls": ["https://food.grab.com/ph/en/cuisines/pizza"], "maxResults": 3}

Discover categories example

{"mode": "discoverCategories", "countryCode": "mm", "maxResults": 3}

GrabFood directory example

{"mode": "directory", "countryCode": "sg", "sitemapCity": "singapore", "maxResults": 3}

maxItems and limit are aliases for maxResults; q, query, and searchTerm are aliases for keyword. Close misspellings such as keywrd are corrected; other unknown fields are ignored with a note. Invalid optional filters can also be ignored.

Every run writes its interpretation to INPUT_REPORT in the default key-value store. Invalid coordinates fail before rows are charged: INVALID_INPUT: latlng — write latitude,longitude, for example 14.5547,121.0244. A start fee can still apply. Examples show input format, not guaranteed current inventory.

Output example

Illustrative merchant row; values depend on the selected location and source.

{
"rowType": "restaurant",
"itemType": "merchant",
"businessType": "FOOD",
"merchantId": "2-C2EYTY3AJ6NZKA",
"name": "Example Kitchen",
"title": "Example Kitchen",
"countryCode": "PH",
"url": "https://food.grab.com/ph/en/restaurant/example/2-C2EYTY3AJ6NZKA",
"rating": 4.6,
"deliveryFee": 29,
"phones": [],
"emails": [],
"scrapedAt": "2026-10-24T08:00:00Z"
}

Export the dataset as JSON, CSV, Excel, XML, RSS, or an HTML table.

Why use this Grab scraper?

  • Pay per delivered row. Attempted pages are not dataset rows.
  • Keep delivered data. Rows already written remain available after a stop. Collection still in progress is not guaranteed to be saved.
  • Inspect problems. RUN_SUMMARY includes notes and warnings; failures can also write ERROR_SUMMARY.
  • Avoid invented details. Missing source fields stay empty; URL-derived names are identified.
  • Several inputs. Submit multiple links through startUrls rather than creating a run per link.
  • No proxy setup. You do not need to set up proxies.

How much does it cost to scrape Grab?

Pricing is pay-per-event. Platform usage is included in these prices. Start events cost $0.005 each, with one event per GB of allocated memory and a minimum of one. Default memory is 1024 MB, so one default-memory start costs $0.005.

Apify planStart at 1024 MBPrice per rowPrice per 1,000 rows
Free$0.005$0.003$3.00
Starter$0.005$0.003$3.00
Scale$0.005$0.0026$2.60
Business$0.005$0.0022$2.20
Platinum$0.005$0.002$2.00
Diamond$0.005$0.0016$1.60
  • maxResults applies per input, defaults to 70, and accepts up to 500. Larger requests are collected in parts of 70.
  • All row types share the limit, including optional menu, branch, category, promotion, and label rows.
  • Free Apify plan limits are 50 rows per run and 3 runs of this Actor, set by the publisher.
  • The whole run stops at Maximum cost per run (maxTotalChargeUsd in the API).

Example: one default-memory run delivering 3 rows on the Free plan costs 3 × $0.003 + $0.005 = $0.014.

What happens when the run timeout is too short

Some Grab collections, such as several startUrls with includeMenuItems: true or a large maxResults, can take longer than the run timeout you chose. In that case the run does not fail. It ends early with the status message "Queued on the collection backend; this run will resume automatically when results are ready (about N s)." and shows as ABORTED for a while.

When the results are ready, the same run starts again by itself, reports "Resumed: delivering N rows.", writes the rows to the same dataset and finishes as SUCCEEDED. Rows that were already delivered are skipped, so no row is delivered or charged twice. You do not need to start another run.

  • This can happen at most 3 times per run. To avoid it, keep the default timeout of 3600 seconds.
  • The synchronous API endpoints (run-sync, run-sync-get-dataset-items) wait at most 300 seconds and can return an empty dataset while the run is paused. For larger jobs, start the run asynchronously and read the dataset after the run reaches SUCCEEDED, or use a webhook on the "succeeded" event.

Use with AI agents and the API

Apify MCP server

Add the Actor to a remote MCP client such as Claude, ChatGPT, Cursor, or VS Code:

https://mcp.apify.com?tools=lentic_clockss/grab-scraper

Sign in with Apify using OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool returns run and dataset IDs; read rows with get-dataset-items. Clients without remote support can use npx @apify/actors-mcp-server --tools lentic_clockss/grab-scraper with APIFY_TOKEN.

Example prompt: “Find 3 pizza restaurants in Makati, Philippines, with Grab Scraper. Return merchant IDs, names, ratings, and URLs.”

Apify API

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("lentic_clockss/grab-scraper").call(
run_input={"keyword": "pizza", "countryCode": "ph", "maxResults": 3}
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row)
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('lentic_clockss/grab-scraper').call({
keyword: 'pizza', countryCode: 'ph', maxResults: 3
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Over HTTP, send the input to POST https://api.apify.com/v2/acts/lentic_clockss~grab-scraper/runs with an Authorization: Bearer <YOUR_APIFY_TOKEN> header. After completion, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json.

Integrations

Use the Integrations tab for Google Sheets, Make, Zapier, n8n, Slack, Airtable, or webhooks. Schedule repeated collection with Apify Schedules.

FAQ

This Actor collects publicly accessible data. You are responsible for complying with Grab's terms and applicable data-protection laws. Processing personal data requires a lawful basis.

Why did my run end as ABORTED?

A cancelled run can show ABORTED. Check its status message and log for the reason. Already delivered rows remain in its dataset; do not assume an aborted run completed collection.

How many results can I get?

Request 1–500 rows per input. Source availability, the shared row limit, free-plan limits, and your maximum charge can reduce delivery. A requested count is not a guarantee.

Why are some fields empty?

Grab does not expose every field on every page. Directory entries are especially sparse. A URL-derived name is not a verified display name; empty contact fields do not prove contacts do not exist.

Can I scrape menus?

Yes. Use restaurant or restaurant links in startUrls with includeMenuItems: true. Listing searches do not fetch menus through this switch.

Can I continue a longer collection?

Pass RUN_SUMMARY.nextCursor as cursor with the same mode, market, location, and query. Keep directory filters unchanged. Deduplicate IDs across runs because live listings can change.

Is this an official Grab API?

No. This is an unofficial scraper, not affiliated with Grab. It does not place orders or access private accounts.

Are member prices or Taiwan supported?

No. GrabUnlimited and other login-only prices, Taiwan, rides, and corporate brand pages are outside this Actor's scope.

Limitations

  • Market selection does not guarantee every mode, city, or language has data.
  • Directory membership does not confirm opening hours, stock, or delivery availability.
  • directory ignores keyword, delivery-location, and menu settings; it does not support businessType: "MART".
  • Delivery-pin coordinates are not merchant coordinates. Public phone, email, person, and website coverage is not guaranteed.
  • Saved-URL detail selection needs recent discovered URLs. An empty or stale collection can fail.
  • Source failures are not reported as confirmed empty results. Read warnings when a run returns fewer rows than requested.

More food delivery and grocery scrapers from the same publisher:

Browse all of our scrapers at apify.com/lentic_clockss.

Support

Report problems or request a field through the Issues tab of this Actor's page. Include the run ID and the input you used.