Google Search Results Scraper avatar

Google Search Results Scraper

Pricing

from $1.00 / 1,000 search results

Go to Apify Store
Google Search Results Scraper

Google Search Results Scraper

Scrape Google Search results by keyword. You get organic results, ads, People Also Ask and related searches, page by page. Pick the country, the language and the Google domain. No API key. A proxy is on by default, because Google now blocks plain requests.

Pricing

from $1.00 / 1,000 search results

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

5

Monthly active users

9 hours ago

Last modified

Share

Google Search Results Scraper: organic listings, ads and People Also Ask for one query

Type one Google query and get the results page back as rows: organic listings with their rank, the ads above them, the People Also Ask questions and the related searches at the bottom. You pick the country, the language, the Google domain and how many pages to follow.

One thing to check before you wire it into anything. The url on a result row is the link exactly as Google printed it, and that is not always the destination: in the real row below it came back as a google.com/goto?url=... redirect, with the publisher's name sitting in displayedUrl instead.

InputOne Google query, operators like site:, quotes and OR included
OutputOne row per organic result, ad, People Also Ask entry or related search
Ceiling100 rows per run, across up to 10 pages
Account neededNone, and no Google API key
Price$1.00 per 1,000 rows, flat on every plan

๐Ÿ” What Google Search Results Scraper does

It runs your query against the Google domain you name, reads the results page, and turns it into four kinds of row.

Organic rows carry the title, the link, the domain, the displayed URL, the snippet and the rank. Ad rows carry the same shape for the paid results Google marks as such. People Also Ask rows carry the question and the answer text Google shows when the box is expanded in the HTML. Related search rows carry the phrases printed at the bottom.

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. Duplicate links are dropped across pages, so a listing that appears twice arrives once.

๐Ÿ“ฅ What you give it

{
"query": "best running shoes site:runnersworld.com",
"countryCode": "US",
"language": "en",
"googleDomain": "google.com",
"maxResults": 20,
"maxPages": 2
}
FieldDefaultWhat it is
querybox starts at best running shoesYour search. site:, intitle:, quoted phrases, OR and minus terms all work.
googleDomaingoogle.comThe Google host, without https://. google.co.uk, google.ca and the rest are fine.
countryCodeUSTwo-letter country, sent as Google's gl.
languageenInterface language, sent as Google's hl.
maxResults10Total rows, 1 to 100, counting all four kinds together. It is also the most a run can bill you.
maxPages1Follow Google's pagination this far, 1 to 10.
includeAdsonReturn the paid results Google marks as ads.
includePeopleAlsoAskonReturn the People Also Ask questions and their answer text.
includeRelatedSearchesonReturn the related phrases from the foot of the page. Read the limit below first.
enableProxyFallbackonLeave it on. Switched off, runs come back with a JS_REQUIRED row and no results.
proxyConfigurationleave it aloneOptional. Your own servers are used exactly as given.

There is one more field the schema does not show: proxyUrls, an array of your own server URLs. Pass it and those are tried first, verbatim.

Setting useApifyProxy to false inside proxyConfiguration does not take effect. The run routes itself either way. If you want your own servers used, list them rather than switching the object off.

๐Ÿ“ค What you get back

A real organic row from a recent run, with the long link and the snippet cut short:

{
"ok": true,
"type": "organic",
"title": "The 15 Best Running Shoes of 2026",
"url": "https://google.com/goto?url=CAESdwHrOzAV7FPP0O3re4bWugQoRsUlWFw65cAN47wAxFn...",
"domain": "google.com",
"displayedUrl": "Runner's World",
"snippet": "Aug 3, 2026 ... For new runners we recommend a shoe like the Brooks Ghost or Nike Pegasus as a starting point. ...Read more",
"rank": 1,
"page": 1,
"query": "best running shoes",
"countryCode": "US",
"language": "en",
"googleDomain": "google.com",
"transport": "proxy_fallback_serp",
"fetchedAt": "2026-09-14T05:43:56.720Z"
}
FieldWhat it is
typeorganic, ad, people_also_ask or related_search. All four land in the same dataset.
urlThe link as Google gave it. Follow it, or read displayedUrl, before treating it as the destination.
rankPosition within its own page, so page 2 starts counting again.
question, answerPeople Also Ask rows only. answer is whatever text Google put in the HTML, which is sometimes empty.
queryThe search you typed. On a related_search row this overwrites the related phrase, which survives only inside url.
pageWhich Google page the row came from, counting from 1.
snippetGoogle's own description text, trailing Read more and all.

๐Ÿงพ Reading the output

Three kinds of row can land in your dataset.

RowHow to spot itBilled as a result
A real resultok: true and a type of organic, ad, people_also_ask or related_searchyes
The sample row_sample: trueno
A diagnosticok: false and an errorCodeno

Filter on ok being true with _sample absent. An empty query writes the sample row and stops, so you can see the shape first.

CodeWhat it means
NO_RESULTSThe page loaded and nothing usable was on it. A query with no matches lands here.
BLOCKEDGoogle would not serve that request. Re-run it or reword the query.
RATE_LIMITEDGoogle answered with a rate limit. Wait and re-run.
JS_REQUIREDGoogle served its JavaScript gate instead of a results page. Turn enableProxyFallback back on.
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.

The Overview table hides answer, displayedUrl and the diagnostic fields, so a run that produced only a diagnostic looks almost blank there. Switch the dataset to JSON to read it.

โ–ถ๏ธ How to run it

  1. Open Google Search Results Scraper and click Try for free.
  2. Put your search in Search query, replacing the example.
  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.

๐Ÿ’ฐ How much does it cost?

$1.00 per 1,000 rows. Flat on every Apify plan, no volume tiers.

Every row that lands is one result, whether it is organic, an ad, a People Also Ask entry or a related search. maxResults caps all four together, so it also caps what a run can bill: set it to 10 and ten rows is the most you can be charged for, however many pages get read.

The sample row, every diagnostic row and a query that finds nothing are not billed as results.

๐Ÿ’ก What people use it for

  • Tracking where a page ranks for a keyword, week by week, with rank and page already split out.
  • Pulling the People Also Ask questions 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 query across google.com, google.co.uk and google.de to compare what each country sees.

๐Ÿšง What it does not do

  • Related searches collapse into one row. Measured on a page carrying nine related phrases: one related_search row came out, and its query held the search that was typed, not the phrase. The phrase is only readable inside url. Turn includeRelatedSearches off if you do not need it.
  • 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.
  • A failure on page two or later throws away the earlier rows. With maxPages above 1, a run that trips on a later page writes a diagnostic and no results. Keep maxPages at 1 when one page is better than nothing.
  • Four kinds of row, and no more. No local pack, no shopping carousel, no news box, no knowledge panel.
  • 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 parser catches up.
  • One query per run. Feed a keyword list by scheduling or looping runs.
  • Rows are a snapshot of that page at that moment. Rankings move daily.

๐Ÿงญ Which Google scraper do you need?

If you wantUse
The web results page for a keywordThis one
News articles, with the publisher's real linkGoogle News Scraper
Images and where they are hostedGoogle Images Scraper
Job postings from the jobs boxGoogle Jobs Scraper
Businesses and placesGoogle Maps Scraper

โ“ Questions people ask

Do I need a Google API key? No. Nothing to apply for, no quota to watch.

Can I search more than one keyword at a time? Not in one run. query takes a single search. Use a schedule or a loop for a list.

Do Google search operators work? Yes. site:, intitle:, quoted phrases, OR and minus terms all go straight through.

Why did I get fewer rows than maxResults? Google decides how much it prints. A narrow query, or one with site: on a small domain, often runs out before your limit does.

Can I schedule it? Yes. Runs are independent, so a daily rank check is just a schedule with the same query.

Is scraping Google Search legal? These are public search results. Apify's write-up on scraping and the law 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.