Building localized B2B prospecting pipelines or regional business indices in Brazil presents a specific infrastructure challenge: international directories often miss secondary municipalities, while national directories hide their listings behind pagination, geographic scoping rules, and inconsistent record formats.
GuiaMais is Brazil's primary online commercial directory, cataloging small to medium enterprises across all 27 Brazilian states (Unidades Federativas). Extracting structured entity data from it—such as full addresses, municipal trade categories, verified status, direct phone numbers, and WhatsApp chat links—requires handling free-text Portuguese taxonomy and pagination logic.
The GuiaMais Brazil Business Directory Scraper automates this extraction over HTTP without requiring browser rendering sessions, account logins, or cookies.
Structuring the GuiaMais Search Pipeline
GuiaMais organizes entities by state, municipality, and business category. When programmatically querying the directory, the primary mode of operation is search, which scopes requests directly against the platform's location-aware index.
The Actor takes several specific input fields to narrow down the dataset before records are emitted:
{
"mode": "search",
"category": "Dentista",
"city": "Rio de Janeiro, RJ",
"state": "RJ",
"minRating": 4,
"verifiedOnly": true,
"maxItems": 50
}
Free-Text Category and Municipality Overrides
While the tool exposes curated dropdown options for roughly 55 commercial categories and 60 major metro areas, Brazilian municipal coverage spans over 5,500 cities.
To scrape outside the curated dropdowns:
-
customCategory: Accepts any free-text Portuguese business descriptor (e.g.,"Loja de Bicicletas","Oficina Mecânica"). This field overridescategory. -
customCity: Accepts any Brazilian municipality using the standard geographic format"City Name, UF"(e.g.,"Piracicaba, SP","Petrópolis, RJ"). This overridescity.
When querying specific listings already indexed in an upstream warehouse, mode: "byUrl" accepts an array of full URLs via the urls property, bypassing the search index entirely to parse the target pages directly.
Detail Enrichment vs. Shallow Result Sets
By default (fetchDetails: false), the scraper pulls only the structured summaries surfaced on search result listing cards. This provides:
- Core identity:
businessId,name,category,categoryUrl,sourceUrl - Address properties:
street,neighborhood,city,state,postalCode,fullAddress - Primary contact channels:
phone,phones[],whatsappNumber,whatsappChatUrl - Listing indicators:
verified,sponsored,plan,openNow,profileCompleteness
Setting fetchDetails: true instructs the Actor to issue an extra HTTP request per matched business, visiting the entity's dedicated profile page. This unlocks secondary attributes:
-
latitudeandlongitudecoordinates, alongside a calculatedmapUrl -
priceRange(when provided by the business) -
openingHours[]: A structured array containing{day, dayEn, hours}breakdowns for each weekday
Because GuiaMais does not expose website URLs or direct email addresses anywhere in its public listings, this Actor does not return email or website fields. If your pipeline strictly requires domain names or SMTP endpoints for outreach, GuiaMais data must be joined downstream against national corporate registration databases (CNPJ registries) using the emitted business name and address tokens.
Workflow: Executing a Targeted Municipal Ingestion Run
To set up an ingestion task using Python and the Apify Client SDK:
- Install the SDK: Ensure your execution environment has the client installed:
pip install apify-client
Define the Task Input: Construct the JSON payload containing the operational scope, setting the state boundary and fetching details for enriched geocoding.
Execute and Poll the Actor:
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run_input = {
"mode": "search",
"customCategory": "Farmácia",
"customCity": "Campinas, SP",
"state": "SP",
"fetchDetails": True,
"maxItems": 100
}
run = client.actor("crawlerbros/guiamais-scraper").call(run_input=run_input)
# Fetch emitted dataset records
dataset_items = client.dataset(run["defaultDatasetId"]).list_items().items
for item in dataset_items:
print(f"Business: {item.get('name')}")
print(f"WhatsApp: {item.get('whatsappChatUrl')}")
print(f"Location: {item.get('latitude')}, {item.get('longitude')}")
print("---")
- Consume the Output: Emitted records preserve Portuguese diacritics and omit empty fields entirely rather than passing empty strings or fabricated zeroes for un-reviewed listings.
Edge Filters: Scoping vs. Post-Processing
The Actor handles filtering at two distinct stages:
-
Search-scoped filtering: The
deliveryOnlyparameter modifies the initial query sent to GuiaMais's internal search endpoint, limiting results strictly to merchants flagged on the platform as offering delivery. -
Post-fetch record filtering: Parameters like
minRating,openNowOnly,hasPhotosOnly,verifiedOnly, andkeywordapply rules against returned attributes before items are emitted to the dataset. For instance,minRating: 4discards any business whose score falls below 4 or that lacks ratings entirely.
Platform Usage and Pricing Structure
The Actor runs on a pay-per-event pricing model alongside standard platform usage.
Direct event charges for this Actor consist of:
- Actor Start: A flat charge of $0.005 per GB of memory allocated to the run, charged once when execution begins.
- Result Event: Emitted per record written to the default dataset. The base price is $0.005 per result under the FREE discount tier. For accounts on Apify discount tiers, the per-result event is priced at $0.00433 (BRONZE), $0.00367 (SILVER), and $0.003 (GOLD, PLATINUM, and DIAMOND).
Platform usage consumed during the run is billed separately at the rates defined by the user's Apify plan.
Handling Schema Constraints in Downstream Pipelines
When integrating GuiaMais records into relational warehouses like PostgreSQL or Snowflake, account for schema sparsity. Fields such as rating, reviewCount, latitude, and priceRange are only populated when the underlying business explicitly maintains them on GuiaMais. If an entity has no public reviews, rating is omitted entirely from the record rather than returned as zero, preventing clean data lakes from confusing unreviewed businesses with poorly rated ones.
The examples here were produced with GuiaMais Brazil Business Directory Scraper. Its README lists the output fields, so you can check a response against the schema before you build on it.
Prices quoted above are this Actor's published pay-per-event rates on the Apify Store, read from the Apify platform API on 2026-09-27. Check the Actor page for the current rates.
Top comments (0)