
Website Content Crawler
scrape.ly/store/querystone/website-content-crawlerAIDeveloper tools
1 monthly user

Scrape Google Maps places for any search term and location: names, addresses, ratings, review counts, categories, opening hours, phones, websites, and coordinates. Export to JSON, CSV, or Excel.
Turn a search term and a place name into a dataset of public Google Maps listings: name, address, rating, hours, phone, and website when Maps already shows them.
For local lead lists, store locators, and market scans that need the search card, not a guessed profile.
searchStringsArray, biased by locationQuery and the results language.GET requests against the public Maps search data. No browser.{
"searchStringsArray": [
"restaurant"
],
"locationQuery": "Konstanz",
"maxCrawledPlacesPerSearch": 20,
"language": "en"
}
One item from a real run of the example input, shortened. Long text is cut and lists show their first entries.
{
"title": "Constanzer Wirtshaus",
"placeId": "ChIJQ1SYOwL3mkcR5uAfq9NPpfU",
"address": "Spanierstraße 3, 78467 Konstanz-Petershausen-West, Germany",
"categoryName": "German restaurant",
"categories": [
"German restaurant",
"Bavarian restaurant"
],
"totalScore": 4.4,
"reviewsCount": 7511,
"location": {
"lat": 47.667655499999995,
"lng": 9.1775302
},
"street": "Spanierstraße 3",
"city": "Konstanz",
"postalCode": "78467",
"neighborhood": "Petershausen-West",
"countryCode": "DE",
"phone": "+1 555 0100",
"phoneUnformatted": "+1 555 0100",
"website": "http://www.constanzer-wirtshaus.de/",
"openingHours": [
{
"day": "Tuesday",
"hours": "11 AM to 11 PM"
},
{
"day": "Wednesday",
"hours": "11 AM to 11 PM"
}
],
"imageUrl": "https://lh3.googleusercontent.com/…",
"imagesCount": 6505,
"fid": "0x479af7023b985443:0xf5a54fd3ab1fe0e6",
"cid": "17700641680977289446",
"kgmid": "/g/11b88lxycm",
"businessProfileId": "10637748826151191896",
"url": "https://www.google.com/maps/search/?api=1&query=Constanzer+Wirtshaus&query_place_id=ChIJQ1SYOwL3mkcR5uAfq9NPpfU",
"searchPageUrl": "https://www.google.com/maps/search/restaurant/@47.66424335,9.1784748,17z?hl=en"
}
searchStringsArray is the list of queries. locationQuery is the city or area. maxCrawledPlacesPerSearch caps each query. language is the Maps hl value, defaulting to en.
placeMinimumStars drops listings under that rating; it takes a number (4.5) or a name (two, twoAndHalf, three, threeAndHalf, four, fourAndHalf). website is allPlaces, onlyWithWebsite, or onlyWithoutWebsite. skipClosedPlaces drops a place only when the record already says it is permanently or temporarily closed. categoryFilterWords with searchMatching all or any filters category text. Filtered-out places do not count toward maxCrawledPlacesPerSearch: with a filter set, the actor reads further down the Maps results (up to about 200 places per search) to fill the limit.
Written from the Maps search record: title, placeId, address, categoryName, categories, totalScore, reviewsCount, location (lat, lng), street, city, postalCode, neighborhood, countryCode, phone, phoneUnformatted, website, openingHours, imageUrl, imagesCount, fid, cid, kgmid, businessProfileId, url, searchPageUrl, searchString, language, rank, isAdvertisement, and scrapedAt.
Also present only when the record already has them: description, subTitle, claimThisBusiness, reserveTableUrl, reviewsDistribution, additionalInfo, additionalOpeningHours, permanentlyClosed, and temporarilyClosed. From the place panel: plusCode, reviewsTags (review topics with how many reviews mention them) and ownerUpdates (posts from the owner), when Google shows them.
$0.0036 per place ($3.60 per 1,000 places), plus platform usage (compute and proxy traffic). A search for 20 places costs $0.072 in place fees.
Every field below can be set in the run form, passed through the API, or saved as a task. Unset fields fall back to the defaults shown.
searchStringsArrayarrayRequiredSearch terms
Search terms to query on Google Maps.
locationQuerystringRequiredLocation
Location used to center the map search, for example New York, USA.
maxCrawledPlacesPerSearchintegerOptionaldefault 20Max places per search
Maximum number of places to return for each search term.
Narrow down which places are returned.
categoryFilterWordsarrayOptionaldefault []Category filter words
Keep places whose category contains these words. Empty keeps every category. Places that do not match do not count toward the limit.
searchMatchingenumOptionaldefault "all"Search matching
Accepted for input compatibility. All or any category filter words must match.
placeMinimumStarsstringOptionaldefault ""Minimum rating
Minimum place rating, as a number such as 4.5 or as two, twoAndHalf, three, threeAndHalf, four or fourAndHalf. Leave empty to keep every rating. With any filter set, the actor reads further down the results until the limit is filled.
websiteenumOptionaldefault "allPlaces"Website filter
Keep all places, only places with a website, or only places without one.
skipClosedPlacesbooleanOptionaldefault falseSkip closed places
Drop places whose status says permanently or temporarily closed.
languagestringOptionaldefault "en"Language
Google Maps language code, for example en.
Every run writes its results to a dataset. Preview it in the dashboard, then export it or read it through the API.
| Field | Type | Description |
|---|---|---|
| title | string | Name of the place |
| subTitle | string | null | Secondary name shown under the title |
| description | string | null | Editorial description of the place |
| placeId | string | null | Google place ID |
| categoryName | string | null | Main category |
| categories | array | null | All categories of the place |
| address | string | null | Full address |
| neighborhood | string | null | Neighborhood |
| street | string | null | Street and house number |
| city | string | null | City |
| postalCode | string | null | Postal code |
| countryCode | string | null | ISO country code |
| location | object | null | Geographic coordinates |
| phone | string | null | Formatted phone number |
| phoneUnformatted | string | null | Phone number without formatting |
| website | string | null | Website of the place |
| totalScore | number | null | Average rating (0-5) |
| reviewsCount | integer | null | Number of reviews |
| reviewsDistribution | object | null | Number of reviews per star rating |
| openingHours | array | null | Opening hours for each day of the week |
| additionalOpeningHours | object | null | Other named weekly schedules, such as delivery or takeout hours |
| plusCode | string | null | Plus code shown on the place page |
| reviewsTags | array | null | Topics listed above the reviews, with the number of reviews that mention them |
| ownerUpdates | array | null | Posts the owner published on the place profile (text, date, imageUrl, url, button) |
| additionalInfo | object | null | About section labels, grouped by section |
| permanentlyClosed | boolean | Place is permanently closed |
| temporarilyClosed | boolean | Place is temporarily closed |
| wasOpenAtScrapeTime | boolean | Place was open when it was scraped |
| claimThisBusiness | boolean | Google offers to claim this business |
| reserveTableUrl | string | null | Table reservation link |
| imageUrl | string | null | Main image of the place |
| imagesCount | integer | null | Number of images |
| fid | string | null | Google feature ID |
| cid | string | null | Google customer ID |
| kgmid | string | null | Google Knowledge Graph ID |
| businessProfileId | string | null | Google Business Profile ID |
| url | string | null | Google Maps link to the place |
| searchPageUrl | string | Google Maps search page the place was found on |
| searchString | string | Search term the place was found for |
| language | string | Language of the results |
| rank | integer | Position in the results |
| isAdvertisement | boolean | Result is an advertisement |
| scrapedAt | string | When the place was scraped (ISO 8601) |
You pay for the events the actor reports, such as each result or page it produces. Platform usage is included in the event prices.
| Event | Charged when | Price |
|---|---|---|
| Scraped place | One Google Maps place saved to the dataset | $0.0036 |
Run this actor from your own code. Swap in your API token and the examples work as-is.
import { ScrapelyClient } from 'scrapely-client'
const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN })
// Start the actor and wait for the run to finish.
const run = await client.actor('cornerledger/google-maps-scraper').call({
"searchStringsArray": [
"coffee shop"
],
"locationQuery": "Seattle, WA",
"maxCrawledPlacesPerSearch": 20
})
// Read the dataset the run produced.
const { items } = await client.dataset(run.defaultDatasetId).listItems()
console.log(items)Tokens live in your account settings. Keep them server-side: a token carries the full permissions of your account.
Connect the Scrape.ly MCP server once and your agent can run this actor as a tool. Pick your tool:
Fetch scrape.ly/agents.md and run cornerledger/google-maps-scraperPaste into Claude Code, Codex, Cursor or any AI agent. It signs you in once in the browser.
{
"mcpServers": {
"scrapely": {
"url": "https://api.scrape.ly/mcp?tools=actors,runs,storage,docs&actors=cornerledger/google-maps-scraper"
}
}
}No key in the file: your client opens the browser to sign you in the first time it connects.
Inputs the developer prepared for common jobs. Open one to see its input, then copy it to your account to run it as-is or adjust it.
Search Google Maps by keyword and city.
Look up a single business without a location.
Places whose category matches a filter word.
Only places with a high rating.
Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.