Google Search Results Scraper - SERP, Ads & People Also Ask avatar

Google Search Results Scraper - SERP, Ads & People Also Ask

Pricing

from $0.97 / 1,000 search results

Go to Apify Store
Google Search Results Scraper - SERP, Ads & People Also Ask

Google Search Results Scraper - SERP, Ads & People Also Ask

Google search results scraper (SERP) for one query or a list: organic results with their rank, ads, People Also Ask questions and related searches, page by page. Pick the country, the language and the Google domain, and use operators like site: and OR. $1.00 per 1,000 organic results.

Pricing

from $0.97 / 1,000 search results

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

27

Total users

8

Monthly active users

16 hours ago

Last modified

Security

Limited permissions

Share

Google search results scraper for your own searches, results pages back as rows: organic listings with their rank, the ads above them, the People Also Ask questions and the related searches at the bottom. One search or a list of up to 100, with the country, language, Google domain, dates and pages you choose.

The url on an organic row is the address of the page itself. Now and then Google won't give one up. That row still arrives, with url and domain set to null, and it is not billed.

InputGoogle searches, typed or pasted as Google search addresses, operators like site:, quotes and OR included
OutputOne row per organic result, ad, People Also Ask entry or related search, with rating, price range and the bold snippet words where Google prints them
Ceiling100 rows per search, across up to 10 pages; 100 searches per run
Account neededNone, and no Google API key
Price$1.00 per 1,000 organic results on the Free plan, a little less on paid plans. Ads, People Also Ask and related searches come free. The free plan's $5 a month covers about 5,000

🔍 What Google Search Results Scraper does

It runs each search against the Google domain you name, reads the results page, and turns it into rows.

Organic rows carry the title, the page's address, the displayed source, the snippet and the rank, plus the snippet's bold words and, on shop and review results, the star rating, review count and price range. Ad rows carry the same shape for the paid results Google marks as such, without the advertiser's address: Google prints only its own click link for an ad and we don't follow it, so url and domain are null there. People Also Ask rows carry the question. Related search rows carry one phrase each from the "People also search for" block.

Set maxPages above 1 and it follows Google's own Next link, page by page, stopping when your row limit is reached or Google runs out of pages. When Google runs out first, a free NO_MORE_PAGES row says how many pages it showed. Duplicate links are dropped across pages.

Filters ride on the same request: dates, results language, sites from one country, a city, and fields that write site:, intitle: or filetype: for you.

📋 What data you get from each Google search result

What you getField
Which kind of row it istype
The listing: title, the page's address and its host, the source Google displays, the snippettitle, url, domain, displayedUrl, snippet
Position within its page, which page, and the next page Google offersrank, page, nextPage
The snippet's bold wordssnippetHighlights
Star rating, review count and price range, when the result shows themrating, reviewCount, ratingSource, priceRange
Sitelinks under a result (with includeSitelinks)sitelinks
People Also Ask: the question and the answer textquestion, answer
Related search phrasetitle on related_search rows
Product cards (with includeProducts)title, price, oldPrice, seller, moreSellers, rating, reviewCount
Sites the AI Overview cites (with includeAiOverviewSources)source, title, url, domain
Optional add-on: each result page's readable textpageText
The search, its settings and the Google address read, on every rowquery, countryCode, language, googleDomain, searchUrl
When the page was readfetchedAt

▶️ How to scrape Google search results

  1. Open Google Search Results Scraper and click Try for free.
  2. Put your search in Search query, replacing the example, and any others in More searches.
  3. Set Maximum results. Ten is a sensible first run.
  4. Change Google domain, Country code and Language if you want another country's view, then click Start.
  5. Download the dataset as JSON, CSV or Excel, or read it from the Apify API.

An empty query writes one labelled sample row and stops, so you can see the shape first.

💰 How much does it cost to scrape Google search results?

$1.00 per 1,000 organic results on the Free plan. Paid plans pay a little less: $0.99 on Starter, $0.98 on Scale and $0.97 on Business. On the free plan, the $5 Apify gives you each month covers about 5,000 organic results.

Only organic results are billed. Ads, People Also Ask entries, related searches, product cards and AI Overview sources arrive free beside them. maxResults caps each search, so it also caps what a search can bill: set it to 10 and ten organic results is the most one search can be charged for.

The sample row, every diagnostic row, an organic result that came without its address, a result left out for falling outside your dates or your site, and a search that finds nothing are not billed. Page text is an optional add-on, off unless you switch it on.

📥 What you give it

{
"query": "best running shoes",
"queries": ["trail running shoes", "running shoes for flat feet"],
"countryCode": "US",
"language": "en",
"googleDomain": "google.com",
"timeRange": "month",
"maxResults": 20,
"maxPages": 2
}
FieldDefaultWhat it is
querynone, the box starts at best running shoesYour search. site:, intitle:, quoted phrases, OR and minus terms all work. A site: search reads Google's plain web results, so it brings no People Also Ask or related searches, and an organic result from another site is left out and not billed.
queriesnoneMore searches, one per line. Each is read on its own, with its own pages and maxResults. 100 searches per run in all.
searchUrlsnoneGoogle search addresses from your browser. The search and its tbs, lr, cr, uule, gl, hl and start are read from each. Only the All tab; only Google's own addresses.
googleDomaingoogle.comThe Google host, without https://. google.co.uk, google.ca and the rest are fine.
countryCodeUSTwo-letter country, sent as Google's gl. A code Google does not know stops the run before any search, with a free BAD_INPUT row.
languageenInterface language, sent as Google's hl, such as de or pt-BR. Checked the same way.
resultsLanguagenoneOnly pages written in this language (Google's lr).
resultsCountrynoneOnly sites Google places in this country, such as FR (Google's cr). Different from countryCode, which is where you search from.
locationnoneSearch as someone in this place: Google's name for it, like Chicago,Illinois,United States, or a uule code.
timeRangenonehour, day, week, month or year.
dateFrom, dateTononeA date range, YYYY-MM-DD. Not together with timeRange. A result whose snippet date is clearly outside the dates is left out and not billed.
exactMatchoffWraps each plain search in quote marks. Searches with quotes, operators or OR are sent as they are.
site, wordsInTitle, wordsInText, wordsInUrlnoneWritten into the search as site:, intitle:, intext: and inurl:.
fileTypesnoneWritten in as filetype:pdf OR filetype:xlsx and so on.
maxResults10Rows per search, 1 to 100, counting organic results, ads and People Also Ask together; the related phrases take one place between them. It is also the most a search can bill you.
maxPages1Follow Google's pagination this far, 1 to 10.
startPage1The first page to read, 1 to 10. A run never reads past page 10.
includeAdsonReturn the paid results Google marks as ads.
includePeopleAlsoAskonReturn the People Also Ask questions, with answer text when the page carries it.
includeRelatedSearchesonReturn the related phrases from the foot of the page, one row each.
includeSitelinksoffFill sitelinks on organic rows. Their addresses are filled on every plan.
includeProductsoffFree product rows for the shopping cards Google prints, text only, on top of maxResults.
includeAiOverviewSourcesoffFree ai_overview_source rows for the sites the AI Overview cites, on top of maxResults. Their addresses are filled on every plan. The overview's own text is never returned.
includePageTextoffOptional add-on: each organic result's page read once, its text in pageText, up to 20,000 characters.
notionConnector, notionParentIdnoneWrite each row as a page into your Notion through an Apify connector. The dataset has them either way.
enableProxyFallbackonOn by default. Switched off, runs can come back with no results.
proxyConfigurationleave it aloneOptional. Your own servers are used exactly as given.

📤 What you get back

A real organic row from a run on 11 October 2026:

{
"ok": true,
"type": "organic",
"title": "Best of Road Running Shoes",
"url": "https://believeintherun.com/shoe-reviews/type/best-of-road/",
"domain": "believeintherun.com",
"displayedUrl": "Believe in the Run",
"snippet": "Independent, run-tested reviews of running shoes, Popular Brands New Balance Nike Asics Hoka Saucony Puma Adidas. These are the Best On Running Shoes Right Now ...",
"rank": 4,
"page": 1,
"query": "best running shoes",
"countryCode": "US",
"language": "en",
"googleDomain": "google.com",
"fetchedAt": "2026-10-11T18:43:56.264Z"
}
FieldHow to read it
urlThe page's own address. null on a result Google gave no address for, and that row is not billed.
domainThe host of url, without www.. null when url is.
rankPosition within its own page, so page 2 starts counting again.
answerPeople Also Ask rows only, and usually null: on our test runs none of the 12 questions came with answer text.
queryThe search as sent to Google, with any operator fields written in. On a related_search row the phrase is in title.
snippetGoogle's own description text, trailing Read more and all.
rating, reviewCountNumbers only. ratingSource says when Google labels it, such as store rating. null on most results.
nextPageThe page number Google offers next, ready for startPage; null on the last page.
transportfirst_try when Google answered the first request for the page, retry when a later try did. Rows and price are the same either way. Runs before 25 October 2026 wrote direct for a first try, and runs before 24 October wrote longer values in place of retry.

🧾 Reading the output

RowHow to spot itBilled as a result
An organic resultok: true, a type of organic and a urlyes
An organic result Google gave no address fora type of organic and url set to nullno
An ad, People Also Ask entry, related search, product card or AI Overview sourceok: true and a type of ad, people_also_ask, related_search, product or ai_overview_sourceno
The sample row_sample: trueno
A diagnosticok: false and an errorCodeno

Filter on ok being true with _sample absent. For the billed results alone, keep the organic rows that have a url.

CodeWhat it means
BAD_INPUTA setting could not be used: a country or language code Google does not know, a malformed date, an address that is not a Google search. problems lists them. Nothing was searched.
NO_RESULTSThe page loaded and nothing usable was on it. A query with no matches lands here.
NOT_SERVEDThis search page was not served this run. Re-run it later. Runs before 13 October 2026 wrote BLOCKED or JS_REQUIRED here.
RATE_LIMITEDGoogle answered with a rate limit. Wait and re-run.
NETWORKGoogle was unreachable or answered badly. A googleDomain that is not a real Google host also lands here rather than saying the value is wrong.
TIME_LIMITThe run got close to its time limit and stopped on its own. The results delivered before that are complete; searchesNotRead names any search it did not reach. Give the run more time, or ask for fewer pages, to get the rest.
INCOMPLETEGoogle did not return a later page (failedPage says which). The results of the pages before it are delivered and billed as usual; nothing is billed for the missing pages.
NO_MORE_PAGESYou asked for more pages than Google showed (pagesRead and pagesAsked give both numbers). Everything read is delivered and billed as usual; this row itself is free.
OFF_QUERY_PAGEGoogle answered a later page with results for a different search, and again when asked a second time. That page is left out and not billed, and the run carries on with the next one. offQueryPages lists every page left out (offQueryPage is the first). Two such pages in a row end the run there.
OFF_SITE_RESULTSA site: search came back with organic results from other sites mixed in. Those were left out and not billed; the results on the site are delivered as usual. offSiteResults is how many, offSitePages on which pages.
OUTSIDE_DATESGoogle returned results dated outside the dates you asked for. Those were left out and not billed. outsideDates is how many.
PARTIALAn extra was not read: further pages of a search whose results kept falling outside your dates, links of free rows, or page text. It says which; nothing was billed for them.

A diagnostic never fails the run, TIME_LIMIT included: a run the time limit stopped before any result came back still ends as succeeded, with an amber status message.

The Overview table hides the newer columns and the diagnostic fields. Switch the dataset to JSON to read them.

💡 What people use it for

  • Tracking where a page ranks for a list of keywords, week by week, with rank and page already split out.
  • Pulling the People Also Ask questions and related searches for a topic to see what the audience actually asks.
  • Checking which advertisers sit above the organic results for a commercial term in one country.
  • Running the same search across google.com, google.co.uk and google.de, or from one city, to compare.

From a seed word to who ranks for it, in three runs:

  1. Run Keyword Autocomplete Scraper on a seed with expandQuestions on, and keep the suggestion values you care about.
  2. Put the best few into Google Trends Scraper's searchTerms with compareKeywords on, to see which one is growing.
  3. Paste the winners here into queries to see who ranks for them today.

🚧 What it does not do

  • With a small maxResults, ads are taken first. Cap a run at 5 on an advert-heavy term and ads can use most of the budget. Switch includeAds off if you only want organic rows.
  • No local pack, news box or knowledge panel, and none of the AI Overview's own text: only the sites it cites.
  • Filters are Google's own. It can ignore one; dates are checked against the snippet, but language, country and city are taken as Google answers them.
  • Ads and People Also Ask are spotted from how Google marks them up, so a layout change on Google's side can leave some of them out until the reading catches up.
  • Rows are a snapshot of that page at that moment. Rankings move daily.
  • It is not an official Google tool. Dami's Studio is independent and is not affiliated with or endorsed by Google, or by any other company named on this page.

🧭 Which Google scraper do you need?

If you wantUse
The web results page for a keyword: organic, ads, People Also AskThis one
What a search box suggests as people typeKeyword Autocomplete Scraper
Interest in a keyword over time and by regionGoogle Trends Scraper
News articles with the publisher's real linkGoogle News Scraper
Image results and the pages they sit onGoogle Images Scraper
The ads a brand runs on GoogleGoogle Ads Transparency Scraper
The same job on Yandex, by regionYandex Search Engine Scraper
Businesses and placesGoogle Maps Scraper

❓ Questions people ask

Do I need a Google API key to scrape Google search results?

No. Nothing to apply for, no quota to watch.

Can I search more than one keyword at a time?

Yes. Put up to 100 searches in queries, or paste Google search addresses into searchUrls. Each one gets its own pages and its own maxResults, and the rows say which search they came from.

Why don't the rankings match what I see on Google?

Google tailors results to where you are, your language and your history. The run sees what a logged-out visitor sees for the googleDomain, countryCode and language you set. To compare, search in a private browser window with the same Google domain.

Why did I get fewer rows than maxResults?

Google decides how much it prints. A narrow query, a date filter, or site: on a small domain often runs out before your limit does. If you asked for more pages than it showed, a free NO_MORE_PAGES row says so.

Can I call it from code or connect it to an AI assistant?

The API tab has code for Python, JavaScript and the CLI. MCP clients like Claude and ChatGPT use https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/google-search-results-scraper; coding assistants can load our skill file. All three bill your Apify account at the same price.

These are public search results. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.

🆘 If something breaks

Open the Issues tab on the actor page. Send the query and the run ID. The errorCode on the diagnostic row usually names the problem on its own.