Google Search Scraper — SERP, AI Overview, Ads & Operators avatar

Google Search Scraper — SERP, AI Overview, Ads & Operators

Pricing

from $3.00 / 1,000 serp pages

Go to Apify Store
Google Search Scraper — SERP, AI Overview, Ads & Operators

Google Search Scraper — SERP, AI Overview, Ads & Operators

Scrape Google Search SERP — organic results, paid ads, related queries, People Also Ask, knowledge panels — with built-in anti-block defenses (AdsBot UA, udm=14, multi-selector parsing, dual-engine HTTP).

Pricing

from $3.00 / 1,000 serp pages

Rating

0.0

(0)

Developer

Muhamed Didovic

Muhamed Didovic

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

20 hours ago

Last modified

Share

Google Search Results Scraper

Scrape Google Search result pages (SERPs) and get clean, structured JSON — organic results, related searches, People Also Ask, knowledge panels, and total result counts — for any query, country, and language.

Built for reliability: a dual-engine HTTP fetcher with real browser TLS impersonation, an 8-deep self-healing selector chain that survives Google's layout rotations, and structural soft-block detection that won't false-reject a valid SERP.

How the Google Search Scraper works

What it extracts

  • Organic results — position, title, URL, displayed URL, description, date, emphasized keywords, sitelinks, and inline product info (rating / reviews / price)
  • Related searches — the "people also search for" / bottom-of-page queries
  • People Also Ask — the expandable Q&A questions (with answer text when present)
  • Knowledge panel — title, subtitle, description, fact attributes (Born, Died, Address, Height, …), and source link
  • AI Overview — detection + the cited source domains for GEO/AEO tracking (the generated prose itself is not available over the proxy — see Limitations)
  • Total results — the "About N results" count
  • Contact emails (opt-in) — turn a SERP into leads: scrape each result's own site for a contact email + people. See Lead enrichment below.
  • Perplexity AI answer (opt-in, BYOK) — a grounded AI answer with citations per query, via Perplexity's official API with your key. See Perplexity AI answer.

Input

FieldTypeDefaultNotes
queriesstring[]One or more search terms. Required.
maxPagesPerQueryinteger1Pages to fetch per query (~10 results each).
resultsPerPageinteger10See the note under Limitations — Google caps this at ~10.
countryCodestringUSTwo-letter country (sets the Google domain + gl).
languageCodestringenInterface/results language (hl).
safeSearchoff/medium/highoffSafeSearch level.
includeRelatedbooleantrueExtract related searches + People Also Ask.
includeKnowledgePanelbooleantrueExtract the knowledge panel.
includeAiOverviewbooleantrueDetect AI Overview + extract its cited sources. Needs appendUdm14: false.
includeAdsbooleantrueAttempt paid-ad extraction (see Limitations).
appendUdm14booleantrueUse Google's clean "Web" layout. Set false to see AI Overviews. Recommended on for max organic stability.
useAdsBotUAbooleanfalseSend the AdsBot-Google user agent.
maxConcurrencyinteger5Parallel requests.
maxRequestRetriesinteger5Retries per page before giving up.
proxyobjectGOOGLE_SERPProxy config. Leave default — see Limitations.

Advanced search filters

Google search operators exposed as structured fields (all folded into the query / URL — you can also type the operators directly inside a queries entry):

FieldTypeOperator / paramNotes
sitestringsite:Restrict to one site. Wins over relatedToSite.
relatedToSitestringrelated:Pages related to a site.
wordsInTitlestring[]intitle:Multi-word entries auto-quoted.
wordsInTextstring[]intext:Words required in body text.
wordsInUrlstring[]inurl:Words required in the URL.
fileTypesstring[]filetype:OR-combined (pdf, docx, …).
forceExactMatchboolean"…"Wrap the query in quotes.
searchLanguagestringlr=lang_XXResults language (distinct from hl).
locationUulestringuule=Exact location code.
quickDateRangestringtbs=qdr:Relative recency: h, d10, w, m6, y1.
afterDate / beforeDatestringtbs=cdr:Absolute bounds (YYYY-MM-DD or MM/DD/YYYY).
includeUnfilteredResultsbooleanfilter=0Include Google's omitted near-duplicates (off by default).
saveHtmlbooleanAttach raw SERP HTML to each row under html (large).
saveHtmlToKeyValueStorebooleanSave HTML to the KV store; add htmlSnapshotUrl to each row.

Lead enrichment (opt-in)

Turn search results into leads. When enrichEmails: true, the top business domains in each SERP get their own site scraped for a contact email + people; the hits are attached to those organic results as contactEmail and emailEnrichment.

FieldTypeDefaultNotes
enrichEmailsbooleanfalseEnable contact-email enrichment.
maxEnrichedDomainsPerPageinteger3Cap unique business domains enriched per page.
  • Best on business-intent queries ("commercial plumbers chicago", "B2B SaaS vendors").
  • Non-business domains (search engines, social, Wikipedia, big marketplaces) are skipped; domains are de-duped per page.
  • Best-effort and free (direct site scrape) — enrichment never fails a scrape.

Perplexity AI answer (opt-in, bring-your-own-key)

Attach a Perplexity (Sonar) AI answer to each query — grounded, with citations. This calls Perplexity's official API with your own key, so you are billed by Perplexity per request (it is not scraping). The answer lands on the page-1 row under perplexity { answer, model, citations, searchResults?, relatedQuestions? }.

FieldTypeDefaultNotes
perplexitySearchbooleanfalseEnable the Perplexity answer.
perplexityApiKeystring (secret)Your key from docs.perplexity.ai. Required.
perplexitySearchRecencyday/week/month/yearRestrict grounding to recent content.
perplexityRelatedQuestionsbooleanfalseAlso return follow-up questions.

Inert unless both the toggle is on and a key is supplied; a Perplexity error never breaks the SERP scrape.

Example input

{
"queries": ["apify pricing 2026", "best web scraping tools"],
"maxPagesPerQuery": 2,
"countryCode": "US",
"languageCode": "en"
}

Output

One dataset item per (query, page):

{
"query": "apify pricing 2026",
"page": 1,
"searchUrl": "http://www.google.com/search?q=apify+pricing+2026&...",
"organicResults": [
{
"type": "organic",
"position": 1,
"title": "Apify pricing - plans for data collection at any scale",
"url": "https://apify.com/pricing",
"displayedUrl": "https://apify.com › pricing",
"description": "...",
"siteLinks": []
}
],
"paidResults": [],
"relatedQueries": [{ "title": "apify free plan", "url": "https://www.google.com/search?q=..." }],
"peopleAlsoAsk": [{ "question": "Is Apify free to use?", "answer": "...", "url": "https://..." }],
"knowledgePanel": null,
"aiOverview": { "detected": true, "textAvailable": false, "sources": [{ "url": "https://ibm.com/...", "domain": "ibm.com" }] },
"totalResults": 1230000,
"selectorUsed": "div.tF2Cxc",
"scrapedAt": "2026-06-25T09:00:00.000Z"
}

selectorUsed tells you which parser variant matched — handy for spotting future Google layout drift.

How it works

  • Dual-engine fetch — tries impit (Rust, real Chrome TLS + HTTP/2 fingerprint) first, falling back to got-scraping. Two independent fingerprints = two chances against bot detection.
  • udm=14 clean layout — by default the scraper requests Google's "Web" tab, which strips the AI Overview and returns stable, parseable markup.
  • Self-healing selectors — organic results run through an 8-deep selector chain (2026 containers first, classic layouts as fallback, plus a class-agnostic a:has(h3) structural net), so a single Google class rename won't zero out a run.
  • Structural soft-block detection — a page is only treated as blocked if it doesn't structurally look like a SERP, so benign /sorry/ footer links never cause a false "blocked".

Limitations & notes

  • Use the default GOOGLE_SERP proxy. Google aggressively blocks datacenter and residential IPs for SERP scraping (JS-challenge / CAPTCHA interstitials). This actor is built around Apify's GOOGLE_SERP proxy group, which is purpose-built for Google and applied automatically. Overriding proxy to RESIDENTIAL or datacenter groups will fail with soft-blocks — leave the proxy at its default.

  • Paid ads (paidResults) are usually empty. Google does not serve ads to SERP-proxy IP ranges, so the ads container comes back empty regardless of the includeAds toggle. Reliable ad capture requires a separate ad-specialized proxy with retries, which this actor does not include. Treat includeAds as best-effort. (Organic results, related searches, PAA, and knowledge panels are unaffected.)

  • AI Overview prose is not available over the proxy. Google server-renders the AI Overview shell (label + citation cards) but generates the answer text client-side, so a no-JS request receives a placeholder. aiOverview therefore returns detected + the cited sources (useful for GEO/AEO — which domains Google cites) with textAvailable: false. The prose itself needs a JS-rendering path, the same wall as paid ads. Requires appendUdm14: false (the default udm=14 strips AI Overviews entirely).

  • resultsPerPage is effectively ~10. Google ignores the num parameter on most modern SERP layouts and returns ~10 results per page. To collect more, raise maxPagesPerQuery rather than resultsPerPage. Pagination always steps by the real page size, so no results are skipped if you set a larger value.

  • Knowledge-panel images are lazy-loaded by Google's JS, so imageUrl may be absent even when the panel is otherwise fully populated.

  • People Also Ask answers are only present when Google pre-expands the card; for most queries you'll get the question and destination URL but no answer text.

  • AI Overview is intentionally excluded by appendUdm14: true. Set it to false if you want the default SERP layout (which can include the AI Overview and more ad/PAA surfaces), at the cost of slightly less stable organic markup.

Tips

  • Keep appendUdm14 on for the most reliable organic extraction.
  • For deep coverage, set maxPagesPerQuery (e.g. 5) instead of resultsPerPage.
  • Use countryCode + languageCode together for accurate localized results (e.g. DE + de, JP + ja).
  • Google search operators work inside queries (site:, intitle:, "exact", OR, -exclude, filetype:).