Google Maps Photos Scraper
Pricing
from $3.00 / 1,000 results
Google Maps Photos Scraper
Extract photos from any Google Maps place - carousel scraping with max-resolution URLs, contributor info, and category metadata.
Pricing
from $3.00 / 1,000 results
Rating
0.0
(0)
Developer
Crawler Bros
Maintained by CommunityActor stats
0
Bookmarked
53
Total users
3
Monthly active users
a day ago
Last modified
Categories
Share
Extract every photo currently exposed by the public Google Maps gallery — including max-resolution image URLs, contributor names, observed upload-date text, captions, and visibly available category tabs (Food & Drink, Indoor, Outdoor, Menu, Videos, etc.). Google can expose a different slice or fewer fields for different places, regions, categories, and anonymous sessions; the actor omits unavailable values rather than inventing them.
What this actor does
Give this actor a Google Maps place URL and it returns up to the requested limit (up to 100,000) for that place. Google may expose fewer photos for a place or category. Records are pushed progressively as the public gallery reveals them. For each photo you get:
- Max-resolution photo URL (full-size, not thumbnail)
- Photo category — the requested category is included when a non-
alltab is visibly selected;allis not stamped onto rows as if it were a Google-published photo category - Contributor name and profile URL (when available)
- Observed upload date text (for example, "2 months ago"); an ISO date is added only when Google publishes a complete calendar date
- Original dimensions + aspect ratio + orientation, when present in the public viewer route
- Caption and tags (when published by the contributor)
- Video flag and duration — distinguishes photos from short clips when exposed by the viewer/grid, with the clip length as Google displays it (
videoDuration, e.g."0:29") - Business context —
businessName,placeId,featureId,placeUrlechoed on every record so the dataset stays joinable. A canonicalChIJ…Place ID is emitted asplaceId; the legacy0x…:0x…token is emitted asfeatureIdand is never placed underplaceId
Use cases
- Build a visual asset library for restaurants, hotels, and venues
- Track menu / interior photo updates over time
- Source UGC photography for travel and food blogs
- Power "what does this place look like" previews in custom apps
- Enrich lead-generation pipelines with visual context
Input
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
placeUrl | String | One of placeUrl/placeId | — | Google Maps place URL; country domains, short links, copied punctuation, and tracking parameters are normalized |
placeId | String | No | — | Canonical Google Place ID beginning with ChIJ; use instead of placeUrl |
maxPhotos | Integer | No | 100 | Maximum number of photos to extract (1–100,000); the source may expose fewer |
photoCategory | Enum | No | all | Filter by tab: all, by_owner, by_visitors, food_and_drink, outdoor, indoor, menu, videos |
enrichDetails | Boolean | No | true | Read each photo's metadata (contributor name/URL, observed upload date, original dimensions, aspect ratio, orientation, caption, tags). Disable for thumbnail-level rows (photo/thumbnail URL, business context, category, video flag and duration). Every surface is walked in both modes, so disabling trims per-photo work rather than skipping the walk. |
proxyConfiguration | Object | No | Apify Proxy | Optional proxy settings |
Examples
Example: enriched place gallery
{"placeUrl": "https://www.google.com/maps/place/Empire+State+Building/@40.7484405,-73.9878584,17z/","maxPhotos": 50,"photoCategory": "all","enrichDetails": true}
Example: fast visitor-photo export
{"placeUrl": "https://www.google.com/maps/place/Sushi+no+Midori/@35.6704396,139.7596577,17z/","maxPhotos": 1000,"photoCategory": "by_visitors","enrichDetails": false}
Example: menu photos only
{"placeId": "ChIJabtoT7hlwokRLECK0SW3_8I","maxPhotos": 100000,"photoCategory": "menu","enrichDetails": true}
Output per photo
One record per photo:
{"recordType": "photo","photoId": "CIHM0ogKEICAgICRye-HxgE","photoIndex": 0,"photoUrl": "https://lh3.googleusercontent.com/gps-cs-s/media=s0","thumbnailUrl": "https://lh3.googleusercontent.com/gps-cs-s/media=w200-h150-k-no","category": "by_visitors","contributorName": "Jane Smith","contributorUrl": "https://maps.google.com/maps/contrib/123...","uploadDateOriginal": "2 months ago","uploadDate": "2026-04-16T00:00:00+00:00","caption": "Sunset view from the observation deck","width": 4032,"height": 3024,"aspectRatio": 1.33,"orientation": "landscape","isVideo": false,"tags": ["sunset", "view", "observation deck"],"businessName": "Empire State Building","featureId": "0x89c259a9b3117469:0xd134e199a405a163","placeUrl": "https://www.google.com/maps/place/Empire+State+Building/...","sourceUrl": "https://www.google.com/maps/place/Empire+State+Building/...","scrapedAt": "2026-06-16T12:00:00+00:00"}
photoIndex is Google's observed tile index in the active gallery/category. It
preserves the source ordering hint, but is not guaranteed to be contiguous or
stable across places, categories, or separate runs.
The place identity is split by form: a canonical ChIJ… token is emitted as placeId, and a legacy 0x…:0x… token as featureId. Only the observed form is emitted — when Google exposes just the legacy token, placeId is omitted (never set to the legacy value).
Empty fields are omitted automatically — no null values in the dataset.
videoDuration holds the clip length exactly as Google renders it on the media tile — mm:ss (for example "0:29"), or h:mm:ss for a clip of an hour or more — rather than a converted seconds count. This keeps the as-displayed value, matching the actor's other observed-text fields (such as uploadDateOriginal) and the sibling Google Maps Directions actor, which keeps the as-displayed duration text and reserves the numeric shape for a distinctly named durationSeconds field. The value is read only from the tile whose media matches the photo's own viewer route, so a neighbouring tile's duration can never be attached.
FAQ
Does it need a proxy or cookies?
No login or authenticated cookies. The actor tries direct public access first, then uses a bounded hardcoded US RESIDENTIAL proxy fallback when the public viewer cannot be verified. Set proxyConfiguration.useApifyProxy to false only for an explicit direct-only diagnostic; cookies are never accepted.
Which categories does Google show? Every place is different. Restaurants typically have Food & Drink + Menu, hotels have Indoor + Outdoor, and landmarks usually have a single "All Photos" tab. A category-specific run emits rows only after the requested tab is visibly selected; if Google does not expose that tab in the anonymous page, the actor fails truthfully instead of returning all-photo rows under the wrong category.
What does enrichDetails actually do?
Every photo surface is walked in both modes, because walking is how photos are enumerated. With enrichment on, each photo's metadata is read: contributor name/URL, observed upload date text, original dimensions, aspect ratio, orientation, caption, and tags. With it off, rows stay at the thumbnail level — photo and thumbnail URL, business context, category, video flag and duration — so contributor, date, caption, tag and dimension fields are omitted.
Are video clips supported?
Yes — short video clips on Google Maps are included when photoCategory is all or videos, with isVideo: true and the clip length Google displays in videoDuration (for example "0:29").
How many photos can I get per place? This actor accepts up to 100,000 photos per run and emits each verified record progressively. Google may expose fewer photos anonymously or limit a gallery by place, region, or category; the actor stops when the public gallery is exhausted.
Data Source
Public Google Maps web UI. No Google API key required.
You are responsible for using these photo records lawfully and in line with Google's terms.
🗺️ Complete Google Maps Scraper Suite
This actor is part of a comprehensive Google Maps data extraction toolkit by crawlerbros. All actors run cookielessly on the free Apify plan with bounded direct, retry, and residential recovery paths, and return clean, structured data.
| Actor | What it does |
|---|---|
| 🏢 Google Maps Business Scraper | Extract business data — name, address, phone, website, rating, reviews, hours, amenities |
| ⭐ Google Maps Reviews Scraper | Scrape reviews with reviewer Local Guide level, photos, mentioned items, owner replies |
| 🕐 Google Maps Business Hours Scraper | Full 7-day hours, timezone, current local time, next open/close, holiday hours |
| 📊 Google Maps Popular Times Scraper | Busy hours histogram for all 7 days + current busyness + typical visit time |
| 📧 Google Maps Email Extractor | Find business emails + social media links by crawling websites |
| 🗺️ Google Maps Area Scanner | Geographic grid scanning — bypass the 120-place limit with bounding box / circle / polygon |
| 💼 Google Maps Leads Scraper | B2B lead generation with email + phone enrichment, US states + global countries |
| 🤖 Google Maps MCP Server | Unified MCP server combining search + reviews for AI assistants |
| 🧭 Google Maps Directions Scraper | A→B routing — distance, duration, traffic, route alternatives for driving/walking/transit |
| 📍 Google Maps Geocoding Scraper | Bidirectional geocoding — address ↔ coordinates, with address components |
| 🔗 Google Maps Similar Places Scraper | "People also search for" / related place discovery — competitor & alternative finder |
| 🍽️ Google Maps Menu Scraper | Restaurant menu items, prices, descriptions, photos |
| 📌 Google Maps Nearby Scraper | Find places near a coordinate point — lightweight POI search by category |
| 📋 Google Maps Place List Scraper | Extract Google's curated "Top X in Y" lists — best hotels/restaurants/things to do |
| 🌍 Google Maps Timezone Scraper | IANA timezone + current local time from coordinates |