TrueLocal AU Directory Listings & Reviews Scraper avatar

TrueLocal AU Directory Listings & Reviews Scraper

Pricing

from $1.20 / 1,000 results

Go to Apify Store
TrueLocal AU Directory Listings & Reviews Scraper

TrueLocal AU Directory Listings & Reviews Scraper

Scrape TrueLocal.com.au business listings by keyword, location, or URL. Extract names, addresses, GPS coordinates, phones, emails, websites, ratings, and review counts. Optional review mode exports individual reviews with author, rating, text, and date. Automatic pagination included.

Pricing

from $1.20 / 1,000 results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

23

Total users

5

Monthly active users

4 days ago

Last modified

Share

TrueLocal Scraper: Business Listings, Contact Details & Reviews

TrueLocal Scraper turns TrueLocal.com.au, the Australian local business directory, into clean structured data. Search by keyword and location, or paste TrueLocal search or profile URLs, to get each business's name, full address, GPS coordinates, phone, email, website, category trail, opening hours and star rating. Switch on the dedicated reviews mode to get every customer review as its own row, with author, star rating, review text and date. Pagination is automatic, so one keyword in one location can walk thousands of listings, and results export to JSON, CSV or Excel, or straight into your app through the API.

Why This Scraper?

  • Three modes in one actor. Search by keyword and location, paste TrueLocal search or profile URLs, or switch to a flat one-row-per-review mode.
  • Rich listing data. Name, full address, GPS coordinates, phone, secondary phone, email, website, category trail, star rating and structured weekly and holiday opening hours.
  • Reviews at no extra page fetch. Reviews are read from the same profile page the actor already opened for other details, and add no billing beyond that page's single enrichment unit.
  • Verified disjoint pagination. Forward auto-pagination walks confirmed non-overlapping result pages, so one search can enumerate thousands of listings without duplicate rows.
  • Cross-product search expansion. Pass several keywords and several locations and every combination is searched.
  • Lean mode for fast enumeration. Turn off profile fetching to get the SERP card alone (name, URL, phone, category) at low cost.
  • Built for schedules. Incremental mode classifies each listing as new, updated, unchanged or vanished on every recurring run, and Resume mode continues one interrupted large crawl.

Use Cases

  • Lead generation and sales prospecting: build contact lists of businesses by category and suburb, with phone, email and website.
  • Local SEO and citation audits: track a client's or competitor's listing, category and star rating over time.
  • Market and location research: map business density and category mix across Australian suburbs and cities.
  • Directory and aggregator sites: mirror a category from TrueLocal and refresh it on a schedule.
  • Review monitoring and reputation tracking: collect raw customer reviews for sentiment analysis or alerts on new reviews.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
id"00000001"
urlhttps://www.truelocal.com.au/sydney-nsw/tlp/sample-listing-00000001
name"Sample Listing Name"
description"The listing's own description text, when the owner wrote one."
primaryCategory"Sample Category"
categories["Sample Category"]
phone"(02) 0000 0000"
secondaryPhonenull
email"contact@example.com"
website"https://example.com"
fullAddress"1 Sample Street, Sydney NSW 2000"
suburb / state / postcode"Sydney" / "NSW" / "2000"
latitude / longitude-33.0 / 151.0
openingHours{ "MONDAY": "0000-2359", "TUESDAY": "0000-2359", ... }
holidayHours{ "New Year's Day": [["2026/01/01", "Open 24 Hours"]] }
ratingValue5
reviewCount6
reviewsReturned6
reviews[{ "author": "Jane D.", "rating": 5, "body": "...", "date": "2024-01-01" }]
scrapedAt"2026-01-01T00:00:00.000Z"
changeType"NEW" (Incremental mode only)

Every listing record also carries categoryCodes (the full category trail's numeric codes), categoryId (a category code read from the search result page, present even in lean mode), image, street, country and permanentlyClosed. In Incremental mode rows also carry changedFields on UPDATED rows plus firstSeenAt and lastSeenAt timestamps; a normal run's row shape is otherwise untouched. description is null for listings whose owner never wrote one, and openingHours values use a 24 hour range format.

Reviews mode (mode: "reviews") returns one flat record per review instead of a nested array: businessId, businessName, businessUrl, businessCategory, businessSuburb, businessState, businessRating, businessReviewCount, reviewIndex, author, rating, reviewBody, datePublished and scrapedAt, so each review carries its business's summary fields without a second lookup.

How to Use

  1. Pick a mode: search (keyword and location), url (paste TrueLocal URLs) or reviews (one row per review).
  2. Fill in Search terms and Locations, or paste TrueLocal search and/or profile URLs.
  3. Turn on Fetch profile pages for address, GPS, email, website, rating and reviews, and Include reviews to nest them; set Max listings and Max pages to size the run.
  4. Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.

Search by keyword and location:

{
"mode": "search",
"searchTerms": ["restaurants"],
"locations": ["Sydney NSW"],
"fetchDetails": true,
"fetchReviews": true,
"maxReviews": 20,
"maxListings": 50
}

Several keywords across several locations (every combination is searched):

{
"mode": "search",
"searchTerms": ["plumber", "electrician"],
"locations": ["Sydney NSW", "Melbourne VIC"],
"maxPages": 5,
"maxListings": 200
}

Supported URL shapes (URL mode):

ShapeExample patternBehaviour
Search/search?search_terms=<what>&geo_location_terms=<where>Walked page by page
Search starting at a later pagesame, with &page=NWalk starts at page N
Browse/find/<keyword>/<location>First page of results only (a warning in the run log says so); use a Search URL to walk every page
Profile/<suburb-state>/tlp/<slug>-<id>Fetched directly as one business

Any other URL (for example other domains) is skipped with a warning in the run log naming the URL, never silently. Use Search mode for those. If you run URL mode without changing the URLs field, it scrapes the example URLs shown (one per supported shape).

URL mode, a search URL and a profile URL together:

{
"mode": "url",
"urls": [
"https://www.truelocal.com.au/search?search_terms=cafe&geo_location_terms=Melbourne+VIC",
"https://www.truelocal.com.au/sydney-nsw/tlp/sample-listing-00000001"
],
"maxPages": 2
}

Reviews mode, one row per review:

{
"mode": "reviews",
"urls": ["https://www.truelocal.com.au/sydney-nsw/tlp/sample-listing-00000001"],
"maxReviews": 50
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/truelocal-com-au-scraper").call(run_input={
"mode": "search",
"searchTerms": ["restaurants"],
"locations": ["Sydney NSW"],
"fetchDetails": True,
})
for listing in client.dataset(run["defaultDatasetId"]).iterate_items():
print(listing["name"], listing["phone"], listing["fullAddress"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/truelocal-com-au-scraper').call({
mode: 'search',
searchTerms: ['restaurants'],
locations: ['Sydney NSW'],
fetchDetails: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Sizing and cost of a run

Each search result page returns roughly 30 listings. Leave Max pages empty to walk every page of a search until it runs out of new results, or set it to cap how deep any one search goes. Max listings caps the total across every keyword and location combination or pasted URL, and stays at 20 by default so a first run stays small; set it to 0 for no cap. Turning on Fetch profile pages is what unlocks address, GPS, email, website, rating and reviews, and it is also what adds the extra billing event per listing opened; leave it off for a fast, low-cost enumeration of names, URLs, phones and categories only.

Resume and incremental mode

Resume (resumeFromRunId) continues one specific interrupted or partial crawl: paste a previous run ID or dataset ID and this run skips listings already collected there (matched by id), returning only the new ones. A checkpoint is also saved automatically as a run progresses, so a run interrupted by a platform migration, or resurrected after a failure, picks back up in the same run without re-collecting or re-billing listings it already saved. No input is needed for that; it happens on its own.

Incremental mode (incrementalMode) is for running the same search again and again on a schedule. The actor remembers the previous run of that search itself, so you never paste a run ID. The first run returns every listing as NEW. Later runs return only NEW and UPDATED listings by default, and unchanged listings are suppressed and not billed unless emitUnchanged is on. REAPPEARED is not produced on an ordinary later run: a listing is only classified REAPPEARED after an earlier run had emitExpired on and completed a full, uncapped scan, which is what records that listing as gone, and a later run then finds it again. Turn on emitExpired to also get EXPIRED rows for listings that vanish, once a run completes that kind of full scan (not capped by Max listings or Max pages, not a resume, and not a pasted search URL that starts after page 1). Change detection ignores the scrape time, the search context fields (searchQuery, location, source, observedAt), the addressStreet / category repeats, yearsInBusiness (it grows every year), the reviews-returned counter, image-link hosts and the order of categories and reviews; use ignoreFieldsForChanges (dotted paths such as reviews.date work) to leave out more fields, which stay in the output. State is scoped automatically to the mode, keywords, locations, URLs and detail settings you use; set stateKey to name or deliberately share a monitoring campaign. In Reviews mode the same NEW/UPDATED/UNCHANGED suppression applies at the listing level, but EXPIRED rows are never produced there, since a flat per-review dataset has no listing-shaped row to represent a vanished listing.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape; the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title (the listing's name) and its key fields flattened to plain text. The complete, full-fidelity record always stays in the Apify dataset.

  1. Authorize a connector once under Apify > Settings > Integrations (Notion, Linear, Airtable or Apify).
  2. Select it in the "Pipe results into your apps" input field. If the picker is empty, you have not authorized a connector yet.
  3. For Notion, also set notionParentPageUrl to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip; the export only runs when a connector is selected.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch, url or reviews.
searchTermsarray["restaurants"]Keywords or categories to search. Every keyword is searched in every location. Used by Search and Reviews modes; ignored if URLs are pasted.
locationsarray["Sydney NSW"]Free-text locations; suburb level is accepted. Enter Australia to search nationwide. A location TrueLocal does not recognise is skipped with a warning (see below).
urlsarray3 example URLs (a search URL, a /find URL and a profile URL)TrueLocal search, /find and/or profile URLs. In Search/Reviews modes, pasting your own URLs here overrides searchTerms and locations; the 3 untouched examples are ignored there.
fetchDetailsbooleanfalseOff by default: runs return the lean SERP card only. Turn on to open each profile page for full address, GPS, email, website, rating and reviews; each page opened for a listing you receive adds one billing unit. In Reviews mode every profile page opened is billed, including listings that have no reviews and so return no rows. Reviews mode and pasted profile URLs always fetch profile pages regardless of this setting.
fetchReviewsbooleanfalseNest a reviews array on each listing record (Search/URL modes). Requires fetchDetails. Reviews add no billing beyond the profile-page unit. Ignored in Reviews mode, which returns review rows as ordinary results.
maxReviewsinteger20Max reviews captured per listing. 0 = all available reviews, capped at 1000 per listing (reviews come from the page already fetched, so there is no extra request).
maxPagesintegernone (unlimited)Max search-result pages per keyword/location or per pasted search URL. Leave empty or 0 to walk every page; the walk stops naturally at the end of results or once Max listings is reached.
searchQueriesstring listnoneAlias of searchTerms, used only when searchTerms is empty, so inputs written for other TrueLocal scrapers work unchanged.
maxBusinessesintegernoneAlias of maxListings, used only when maxListings is not set.
maxListingsinteger20Stop after this many listings across all searches. 0 = unlimited (bounded only by the natural end of results or Max pages).
resumeFromRunIdstringnoneA previous run ID or dataset ID to continue a large crawl across separate runs. Listings already collected there are skipped.
incrementalModebooleanfalseTurn on for daily or recurring monitoring of the same search. See "Resume and incremental mode" above.
stateKeystringnoneOptional name for a monitoring campaign, so its state stays stable or is deliberately shared. Auto-derived from mode, keywords, locations, URLs and detail settings when left empty.
emitUnchangedbooleanfalseIncremental mode only. Also return (and bill) listings unchanged since the last run, marked UNCHANGED.
emitExpiredbooleanfalseIncremental mode only, Search/URL modes only. Also return (and bill) listings no longer found, marked EXPIRED, once a run has fully scanned the search.
ignoreFieldsForChangesstring listemptyIncremental mode only. Field names (dotted for nested, e.g. reviews.date) that never turn a listing into UPDATED; they stay in the output.
proxyobjectApify Residential (AU)Proxy configuration. AU residential is recommended for the most consistent results.
mcpConnectorsarraynoneOptional: send a summary of each record to apps you authorized under Integrations.
notionParentPageUrlstringnoneNotion connector only: page under which item pages are created.
maxNotifyListingsinteger50Cap on items written to each connector per run. Does not affect the dataset.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"id": "00000001",
"url": "https://www.truelocal.com.au/sydney-nsw/tlp/sample-listing-00000001",
"name": "Sample Listing Name",
"description": "The listing's own description text, when the owner wrote one.",
"categories": ["Sample Category"],
"primaryCategory": "Sample Category",
"categoryCodes": ["00000000"],
"categoryId": "00000000",
"phone": "(02) 0000 0000",
"secondaryPhone": null,
"email": "contact@example.com",
"website": "https://example.com",
"image": "https://example.com/photo.jpg",
"street": "1 Sample Street",
"suburb": "Sydney",
"state": "NSW",
"postcode": "2000",
"country": "AU",
"fullAddress": "1 Sample Street, Sydney NSW 2000",
"latitude": -33.0,
"longitude": 151.0,
"openingHours": {
"MONDAY": "0000-2359", "TUESDAY": "0000-2359", "WEDNESDAY": "0000-2359",
"THURSDAY": "0000-2359", "FRIDAY": "0000-2359", "SATURDAY": "0000-2359", "SUNDAY": "0000-2359"
},
"holidayHours": { "New Year's Day": [["2026/01/01", "Open 24 Hours"]] },
"permanentlyClosed": false,
"ratingValue": 5,
"reviewCount": 6,
"reviewsReturned": 6,
"reviews": [
{ "author": "Jane D.", "rating": 5, "body": "Review text, when reviews are present on the listing.", "date": "2024-01-01" }
],
"scrapedAt": "2026-01-01T00:00:00.000Z",
"addressStreet": "1 Sample Street",
"category": "Restaurants",
"slogan": null,
"yearsInBusiness": null,
"searchQuery": "restaurants",
"location": "Sydney NSW",
"source": "truelocal.com.au",
"observedAt": "2026-01-01T00:00:00.000Z"
}

addressStreet repeats street and category repeats primaryCategory. slogan and yearsInBusiness come from the search card or the profile page and are null when the listing does not publish them. searchQuery and location show which search produced the row (null for pasted profile URLs). Businesses that serve an area rather than a street address have null street, suburb, state and postcode. Enter Australia as the location to search nationwide. If TrueLocal does not recognise a location it silently shows all-Australia results, so the actor skips that search, logs a warning naming the location, and neither returns nor bills those rows; try a suburb and state such as "Melbourne VIC".

Dataset views. The Output tab offers a Detail view (full profile fields), a Changes view (changeType and changedFields in Incremental mode) and a Business reviews view (one row per review with its business). A run summary is saved to the OUTPUT record.

Plan Requirement

TrueLocal sits behind an edge filter that rejects many requests with an "Attention Required" error page, so a connection that is not accepted yields no results. The default connection is Apify's residential proxy group set to country AU, which needs a plan that includes residential proxies; plain datacenter connections are not reliable for this site. If the selected connection is unavailable (for example on Apify free plans, which do not include residential proxies), the run logs: "The selected connection is unavailable to this run." and continues on a backup connection, where some pages may still be unavailable. Pages served that way are noted in the log ("Served over the backup connection"). You can also supply your own proxy URLs in the proxy field.

If no usable page could be loaded, the run ends as failed with a plain message instead of an empty "succeeded" run: "The proxy connection was refused for this account, so no page could be read" (plan without proxy access), "No results: residential proxies are unavailable on this run ... and the backup connection could not load the requested TrueLocal pages", or "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search." Each request has a 25 second limit and is retried on a different connection when rejected.

FAQ

How much does it cost?

You pay per record returned, plus one extra billing unit each time the actor opens a business's profile page for full details. Reviews add no further units. The Pricing tab on the actor page shows the current rates. Use Max listings and Max pages to cap the cost of any run.

This actor collects only publicly available Australian business-directory data already shown on TrueLocal's own listing pages: names, contact details, categories, ratings and reviews. You are responsible for how you use the results: follow TrueLocal's terms and the laws that apply to you, and get legal advice before any commercial redistribution, especially of reviews.

Can I get only new or changed listings on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Every scheduled run then returns only NEW and UPDATED listings by default, and unchanged ones are not billed. REAPPEARED listings only appear after an earlier run that had Emit expired on and completed a full, uncapped scan; only then does a later reappearance get classified as REAPPEARED instead of NEW.

What is the difference between Resume and Incremental mode?

Resume (resumeFromRunId) continues one specific interrupted or partial crawl by skipping listings a past run or dataset already collected; use it to finish one large catalogue walk across multiple runs. Incremental mode is for running the same search again and again, for example daily, and getting only what changed; it remembers its own state, so you never paste a run ID. Turning both on together for a search that already has saved incremental state fails the run on purpose, so remove one of the two.

Why does a run fail instead of returning an empty dataset?

The run fails outright when resumeFromRunId does not match a run or dataset your account can read, when Incremental mode is combined with resumeFromRunId on a search that already has saved incremental state, or when no usable page could be loaded at all (see Plan Requirement). Partial failures finish as a completed run with a partial dataset and a warning in the log. Re-run it; a fresh run picks a new connection.

Can I use it with AI agents or MCP?

Yes. Call the actor from any Apify integration or MCP client, and use the "Pipe results into your apps" field to send a digest of each record to Notion, Linear or Airtable after the scrape finishes.

πŸ”— Want more leads data?

Pair this actor with these related scrapers from the same team:

πŸ“‡ Herold.at Scraper
Scrape Herold.at business listings across Austria into clean JSON. Extract names...
πŸ“‡ 2GIS
Extract business and place data from 2GIS.com at scale. Get names, addresses, phones...
πŸ“‡ Childcare AU
Scrape Australia’s largest childcare directory careforkids.com.au with long day care...
πŸš— EasyAuto123 Scraper
Scrape EasyAuto123 vehicle listings into clean structured data. Extract prices, VINs...
πŸ“‡ Yellow Pages NZ
Scrapes business listings from Yellow.co.nz (New Zealand Yellow Pages). Extract...
πŸ“‡ Local.ch
Pull structured company data from local.ch, including name, address, GPS, phone, email...

πŸ‘‰ Browse all abotapi scrapers

πŸ’¬ Support

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • πŸ› οΈ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.