Google SERP & SEO Scraper avatar

Google SERP & SEO Scraper

Pricing

from $5.00 / 1,000 scraped search result pages

Go to Apify Store
Google SERP & SEO Scraper

Google SERP & SEO Scraper

Scrape Google SERPs for organic rankings, paid ads, AI Overview, People Also Ask & keyword SEO metrics. Track competitors, domain traffic & ad spend. no proxies or CAPTCHAs. Perfect for SEO agencies, marketers & developers.

Pricing

from $5.00 / 1,000 scraped search result pages

Rating

5.0

(1)

Developer

Dxbear

Dxbear

Maintained by Community

Actor stats

2

Bookmarked

2

Total users

2

Monthly active users

a day ago

Last modified

Share

🔍 Google SERP & SEO Scraper

enter image description here

A reliable Google search results scraper and SEO data API for developers, marketers, and growth teams.

Google SERP tool handles web scraping Google search results for you. scrape organic rankings, paid ads, AI Overview, "People Also Ask," related searches, keyword difficulty scores, competitor rankings, domain traffic history, and advertiser intelligence, all returned as structured, ready-to-use JSON from a single API call.

Whether you're building a competitor keyword research tool, tracking rankings at scale, or just need clean SERP data without the infrastructure headache — no proxies to manage, no CAPTCHAs to solve, no HTML to parse. Just clean data.


🚀 What This Google SERP Scraper Does

Use this actor as your rank tracking API and SEO data API in one — every keyword you run returns a full SEO and SERP data package, no manual searching required:

📦 Data Point📝 What You Get
🤖 AI OverviewFull text of Google's AI-generated answer box
🏆 Organic Search ResultsRanked positions, titles, URLs, and snippets
💰 Paid / Sponsored AdsScrape Google Ads copy, display URLs, and advertiser domains directly from live SERPs
People Also Ask (PAA)Related questions Google surfaces for the query
🔗 Related SearchesSuggested keyword variations at the bottom of the SERP
📊 Keyword SEO MetricsKeyword difficulty, click potential, domain diversity, top-100 breakdown
🥇 Competitor Ranking AnalysisBuilt-in competitor keyword research tool data — who ranks where, position changes, estimated traffic value per competitor
📈 Domain Traffic InsightsHistorical organic/paid traffic, ad spend, and domain authority trends
🗂️ Historical Ad ArchivePast ad creatives run against a keyword, with dates and advertiser domains
📢 Active Advertiser DomainsEvery domain currently bidding on a keyword

Every field is documented in the .actor/dataset_schema.json, and every field gracefully handles missing data — so your pipeline never breaks on an empty AI Overview or a keyword with no paid ads.

📍 Note: keyword_seo_metrics, serp_competitor_analysis, domain_traffic_insights, historical_paid_advertisements, and active_advertiser_domains (the SEO/competitor intelligence fields) are currently available for 32 countries. Other supported countries still return full SERP data (organic, ads, AI Overview, PAA, related searches) — just without SEO metrics.

⚙️ How It Works

  1. Input your target keyword(s), along with optional location, language, and device settings
  2. The actor requests the live Google SERP and parses every feature block.
  3. Output lands in your Apify dataset — one structured item per keyword — ready to export or query via API
{
"ai_summary": "<string|null>",
"organic_search_results": [
{
"name": "<string|null>",
"link": "<string|null (uri)>",
"text": "<string|null>",
"position": "<integer|null>"
}
],
"paid_sponsored_results": [
{
"position": "<integer|null>",
"title": "<string|null>",
"displayUrl": "<string|null>",
"url": "<string|null>",
"domain": "<string|null>",
"description": "<string|null>"
}
],
"frequently_asked_questions": [
{
"position": "<integer|null>",
"question": "<string|null>"
}
],
"related_search_queries": [
{
"position": "<integer|null>",
"text": "<string|null>",
"link": "<string|null>"
}
],
"extracted_links": ["<string (uri)>"],
"extracted_domains": ["<string>"],
"raw_html_content": "<string|null>",
"keyword_seo_metrics": {
"keywordSEODifficulty": "<number|null>",
"top100NumberOfHomepages": "<integer|null>",
"top100GovEduMilDomains": "<integer|null>",
"top100TitleContainsKeyword": "<integer|null>",
"top100UrlContainsKeyword": "<integer|null>",
"maxOrganicMonthlyClicks": "<number|null>",
"maxOrganicMonthlyValue": "<number|null>",
"top100DomainDiversity": "<number|null>",
"top100Wiki": "<boolean|null>",
"top100Facebook": "<boolean|null>",
"top100Twitter": "<boolean|null>",
"top100YouTube": "<boolean|null>",
"top100Pinterest": "<boolean|null>",
"top100Tumblr": "<boolean|null>",
"top100LinkedIn": "<boolean|null>"
},
"serp_competitor_analysis": [
{
"keyword": "<string|null>",
"domain": "<string|null>",
"url": "<string|null>",
"title": "<string|null>",
"domainAppearances": "<integer|null>",
"position": "<integer|null>",
"positionChange": "<integer|null>",
"searchVolume": "<number|null>",
"totalMonthlyClicks": "<number|null>",
"totalHomepages": "<integer|null>",
"estimatedOrganicClicks": "<number|null>",
"estimatedClickValue": "<number|null>",
"rankingDifficulty": "<number|null>",
"dateSearched": "<string|null (date-time)>",
"uri": "<string|null (uri)>"
}
],
"domain_traffic_insights": [
{
"domain": "<string|null>",
"domainStats": [
{
"searchDate": {
"dateString": "<string|null>",
"month": "<integer|null>",
"year": "<integer|null>"
},
"averageOrganicRank": "<number|null>",
"monthlyPaidClicks": "<number|null>",
"averageAdRank": "<number|null>",
"totalOrganicResults": "<number|null>",
"monthlyBudget": "<number|null>",
"monthlyOrganicValue": "<number|null>",
"totalAdsPurchased": "<number|null>",
"monthlyOrganicClicks": "<number|null>",
"strength": "<number|null>",
"totalInverseRank": "<number|null>",
"hasData": "<boolean|null>"
}
],
"totalResults": "<integer|null>"
}
],
"historical_paid_advertisements": [
{
"keyword": "<string|null>",
"position": "<integer|null>",
"totalAds": "<integer|null>",
"dateSearched": "<string|null (date-time)>",
"title": "<string|null>",
"bodyHtml": "<string|null>",
"displayUrl": "<string|null>",
"url": "<string|null>",
"domain": "<string|null>",
"searchVolume": "<number|null>",
"keywordDifficulty": "<number|null>",
"countryCode": "<string|null>",
"costPerClick": "<number|null>",
"isNsfw": "<boolean|null>"
}
],
"active_advertiser_domains": ["<string>"]
}

⚡ Getting Started

Ready to try this Google search results scraper? You'll be scraping your first SERP in under two minutes and Apify gives every new account $5 in free credits, so you can test it at zero cost.

  1. Create a free Apify account — you'll get $5 in credits automatically, no card required
  2. Open the actor at apify.com/dxbear/Google-SERP-SEO-Scraper, or just hit Try for free
  3. Go to the Input tab and fill in your query. Here's a working example:
{
"country": "US",
"includeSerpSeoData": true,
"language": "en",
"page": 10,
"query": "Email Marketing",
"returnRawHtml": false
}
  1. There are also location and uule fields for advanced geo-targeting. you can leave these empty for now, they're optional
  2. Click Run That's it. Within seconds you'll have a full SEO data API response for your keyword — organic rankings, paid ads, AI Overview, and every other data point covered below — landing straight in your dataset.

🧾 Input Fields Explained

Every field you can configure on the Input tab, what it does, and when to use it:

FieldTypeRequiredWhat It Does
🔍 querystring✅ YesYour search term — anything you'd type into Google (e.g. "best proxy"). This is the only required field.
📱 deviceselectOptionalSimulates Desktop or Mobile search results. Google serves different SERP layouts and features depending on device, so pick the one matching your target audience. Defaults to desktop.
📄 pageinteger (1–10)OptionalNumber of result pages to scrape. 1 returns just the first page; higher values page deeper into results for more organic listings. Defaults to 1.
🌍 languageselectOptionalTwo-letter language code (en, fr, de, es, etc.) that controls the language Google returns results in. Defaults to en (English). 27 languages are supported.
🗺️ countryselectOptionalTwo-letter country code that controls which country's Google index and localized results you're querying. Defaults to US. This actor supports 90+ countries for standard SERP scraping — see the full list in the actor's country selector. Note: SEO metrics (via includeSerpSeoData) are limited to 32 of these countries — see the note below the feature table.
⏱️ timeFilterselectOptionalRestricts results to a specific freshness window: past hour, day, week, month, or year. Leave empty ("") for Any time — the default — if you don't need to filter by recency.
📍 uulestringOptionalGoogle's UULE parameter for pinpoint geographic targeting (encodes an exact physical location, down to the city/neighborhood level). Use this if you need hyper-local results beyond what country alone provides. Leave blank if not needed.
🏙️ locationstringOptionalA human-readable location name (e.g. "New York, NY") for localized results — a simpler alternative to uule when you don't have a pre-encoded UULE string. Leave blank if not needed.
🗂️ returnRawHtmlbooleanOptionalWhen true, includes the raw, unparsed HTML of the Google SERP in the output — useful for debugging or building your own custom parser on top of this actor's results. Defaults to false. Adds significant payload size, so only enable it if you need it.
📊 includeSerpSeoDatabooleanOptionalWhen true, adds keyword SEO metrics, competitor rankings, domain traffic history, ad archive, and active advertiser data to the output. ⚠️ Only available for 32 supported countries (see the note below the feature table) — results may be incomplete or unavailable elsewhere. Defaults to false.

💡 Tip: The only field you must set is query. Everything else has a sensible default, so you can start with a minimal input like { "query": "best proxy" } and add fields as you need more control.



🌍 Supported SEO Data Countries (32)

  • 🇺🇸 US — United States
  • 🇬🇧 UK — United Kingdom
  • 🇩🇪 DE — Germany
  • 🇫🇷 FR — France
  • 🇦🇷 AR — Argentina
  • 🇦🇹 AT — Austria
  • 🇦🇺 AU — Australia
  • 🇧🇪 BE — Belgium
  • 🇧🇷 BR — Brazil
  • 🇨🇦 CA — Canada
  • 🇨🇱 CL — Chile
  • 🇨🇿 CZ — Czech Republic
  • 🇩🇰 DK — Denmark
  • 🇫🇮 FI — Finland
  • 🇮🇳 IN — India
  • 🇮🇪 IE — Ireland
  • 🇮🇹 IT — Italy
  • 🇯🇵 JP — Japan
  • 🇲🇽 MX — Mexico
  • 🇳🇱 NL — Netherlands
  • 🇳🇿 NZ — New Zealand
  • 🇳🇴 NO — Norway
  • 🇵🇱 PL — Poland
  • 🇵🇹 PT — Portugal
  • 🇸🇬 SG — Singapore
  • 🇿🇦 ZA — South Africa
  • 🇪🇸 ES — Spain
  • 🇸🇪 SE — Sweden
  • 🇨🇭 CH — Switzerland
  • 🇹🇷 TR — Turkey
  • 🇺🇦 UA — Ukraine
  • 🇻🇪 VE — Venezuela

📤 Example Output

Once your run finishes, every keyword you scrape lands in your dataset as one structured item — clean JSON you can query, export, or pipe into your own tool. Raw HTML is excluded by default; it's only included if you enable the returnRawHtml input option.

Here's what a real run for the keyword "Email Marketing" produced:

SERP scrape overview screenshot Dataset output screenshot

📝 Example data (trimmed)

AI Overview:

Email marketing is a digital strategy that involves sending targeted commercial messages to customers who have opted in to receive them...

Top organic results:

PositionTitleURL
1Email Marketing: Everything you need to knowmailchimp.com/marketing-glossary/email-marketing
2What Is Email Marketing? Benefits + Best Practicescoursera.org/articles/email-marketing
7Email marketingen.wikipedia.org/wiki/Email_marketing

Paid ads captured on the same SERP:

AdvertiserDomain
Constant Contactconstantcontact.com
ActiveCampaignactivecampaign.com
Brazebraze.com

Keyword SEO metrics:

MetricValue
Keyword difficulty32 / 100
Max organic monthly clicks3,500
Domain diversity0.53

People Also Ask:

  • How do I start email marketing?
  • What is the best free email marketing?
  • What does email marketing do?
  • Can I earn from email marketing?

💻 JSON output example

{
"ai_summary": "Email marketing is a digital strategy that involves sending targeted commercial messages to customers who have opted in to receive them...",
"organic_search_results": [
{
"name": "Email Marketing: Everything you need to know",
"link": "https://mailchimp.com/marketing-glossary/email-marketing/",
"position": 1
},
{
"name": "Email marketing",
"link": "https://en.wikipedia.org/wiki/Email_marketing",
"position": 7
}
],
"paid_sponsored_results": [
{
"title": "Email Marketing",
"url": "https://www.constantcontact.com/landing7/email-marketing-campaign",
"domain": "constantcontact.com",
"description": "Constant Contact® Email Marketing That Works — Send Better Emails, Grow Your Email List, And Get More Leads."
}
],
"keyword_seo_metrics": {
"keywordSEODifficulty": 32,
"maxOrganicMonthlyClicks": 3500,
"top100DomainDiversity": 0.5263
},
"frequently_asked_questions": [
{ "position": 1, "question": "How do I start email marketing?" },
{ "position": 2, "question": "What is the best free email marketing?" }
]
}

Results are available as JSON, JSONL, CSV, or Excel (XLSX) — or query the dataset directly via the Apify API.


📋 Output Fields Reference

Every field in the dataset, fully documented. All fields are nullable and default to an empty value if that SERP feature wasn't present on the page — so a missing AI Overview or an empty ad list will never break your pipeline.

🤖 ai_summary

FieldTypeDescription
ai_summarystring | nullRaw text of Google's AI Overview / featured snippet block for the query, including embedded source labels. null if no AI Overview was present on the SERP.

🏆 organic_search_results (array)

FieldTypeDescription
namestring | nullResult title as displayed on the SERP.
linkstring | nullDestination URL of the result.
textstring | nullSnippet/description text shown under the result. May contain truncation markers.
positioninteger | null1-indexed organic rank position on the page.

💰 paid_sponsored_results (array)

FieldTypeDescription
positioninteger | nullAd's rank position on the SERP.
titlestring | nullAd headline text.
displayUrlstring | nullHuman-readable display URL shown in the ad.
urlstring | nullActual destination/landing URL.
domainstring | nullAdvertiser's root domain.
descriptionstring | nullAd body copy.

null or an empty array when no ads were shown for this query/location/session.

frequently_asked_questions (array) — "People Also Ask"

FieldTypeDescription
positioninteger | null1-indexed display order of the question in the PAA box.
questionstring | nullThe full question text as shown by Google.

🔗 related_search_queries (array)

FieldTypeDescription
positioninteger | null1-indexed display order.
textstring | nullThe suggested search phrase.
linkstring | nullRelative or absolute Google search URL for this related query.
FieldTypeDescription
extracted_linksarray<string> | nullFlat, deduplicated list of every outbound URL found across all SERP features on the page.
extracted_domainsarray<string> | nullFlat, deduplicated list of root domains parsed from extracted_links.

🗂️ raw_html_content

FieldTypeDescription
raw_html_contentstring | nullFull raw HTML of the fetched SERP page — only populated if returnRawHtml was enabled on input. null by default to keep dataset size small.

📊 keyword_seo_metrics (object)

⚠️ Only populated when includeSerpSeoData is enabled on input, and only for supported countries.

FieldTypeDescription
keywordSEODifficultynumber | null (0–100)Composite difficulty score estimating how hard it is to rank organically for this keyword.
top100NumberOfHomepagesinteger | nullCount of homepage URLs (root domain only) within the top 100 ranking results.
top100GovEduMilDomainsinteger | nullCount of .gov / .edu / .mil domains within the top 100 results.
top100TitleContainsKeywordinteger | nullCount of top-100 results whose page title contains the exact keyword.
top100UrlContainsKeywordinteger | nullCount of top-100 results whose URL contains the exact keyword.
maxOrganicMonthlyClicksnumber | nullEstimated maximum monthly organic clicks achievable for the #1 ranking position.
maxOrganicMonthlyValuenumber | nullEstimated USD value of maximum monthly organic traffic, based on CPC.
top100DomainDiversitynumber | null (0–1)Ratio of unique domains to total results in the top 100 — higher means less domain concentration.
top100Wiki / top100Facebook / top100Twitter / top100YouTube / top100Pinterest / top100Tumblr / top100LinkedInboolean | nullWhether a result from that platform appears in the top 100.

🥇 serp_competitor_analysis (array)

FieldTypeDescription
keywordstring | nullThe keyword this ranking data applies to.
domainstring | nullRoot domain of the ranking competitor.
urlstring | nullExact ranking URL.
titlestring | nullPage title of the ranking result.
domainAppearancesinteger | nullNumber of times this domain appears anywhere in the tracked result set.
positioninteger | nullCurrent organic rank position.
positionChangeinteger | nullChange in rank position since the previous tracked check (positive = moved up).
searchVolumenumber | nullEstimated monthly search volume for the keyword.
totalMonthlyClicksnumber | nullEstimated total monthly clicks across all results for this keyword.
totalHomepagesinteger | nullCount of homepage-only URLs in the tracked result set.
estimatedOrganicClicksnumber | nullEstimated monthly organic clicks this specific result receives.
estimatedClickValuenumber | nullEstimated USD value per click (CPC-derived) for this position.
rankingDifficultynumber | null (0–100)Difficulty score for ranking at this position.
dateSearchedstring | null (date-time)Timestamp this ranking snapshot was captured. May be a placeholder epoch value if unavailable.
uristring | nullCanonical URI, typically identical to url.

📈 domain_traffic_insights (array)

FieldTypeDescription
domainstring | nullThe domain this traffic data applies to.
domainStatsarrayList of monthly traffic snapshots (see below).
totalResultsinteger | nullTotal number of results recorded for this domain.

Each domainStats entry contains:

FieldTypeDescription
searchDateobject | null{ dateString, month, year } — the period this snapshot covers.
averageOrganicRanknumber | nullDomain's average organic ranking position that month.
monthlyPaidClicksnumber | nullEstimated monthly clicks from paid ads.
averageAdRanknumber | nullDomain's average paid ad position that month.
totalOrganicResultsnumber | nullTotal organic results the domain appeared in.
monthlyBudgetnumber | nullEstimated monthly paid-ad spend in USD.
monthlyOrganicValuenumber | nullEstimated USD value of monthly organic traffic.
totalAdsPurchasednumber | nullTotal number of ads purchased that month.
monthlyOrganicClicksnumber | nullEstimated monthly clicks from organic results.
strengthnumber | null (0–100)Composite domain authority/strength score.
totalInverseRanknumber | nullAggregate inverse-rank metric (higher favors better average positions).
hasDataboolean | nullWhether real data was found for this domain/period.

🗃️ historical_paid_advertisements (array)

FieldTypeDescription
keywordstring | nullThe keyword this historical ad ran against.
positioninteger | nullAd's rank position at capture time.
totalAdsinteger | nullTotal number of ad extensions/sitelinks bundled with this ad.
dateSearchedstring | null (date-time)When this ad creative was captured.
titlestring | nullAd headline text.
bodyHtmlstring | nullRaw HTML markup of the ad body/extensions as rendered at capture time.
displayUrlstring | nullHuman-readable display URL shown in the ad.
urlstring | nullActual destination/landing URL (may be a Google redirect wrapper).
domainstring | nullAdvertiser's root domain. Empty string if unresolvable (e.g. about:blank).
searchVolumenumber | nullEstimated monthly search volume at time of capture.
keywordDifficultynumber | null (0–100)Difficulty score at time of capture.
countryCodestring | nullISO country code the ad was captured in.
costPerClicknumber | nullEstimated CPC for this ad, where available.
isNsfwboolean | nullWhether the ad creative was flagged NSFW.

📢 active_advertiser_domains (array)

FieldTypeDescription
active_advertiser_domainsarray<string> | nullFlat list of domains currently bidding on this keyword. May contain duplicates, which reflect ad frequency/weight rather than being a data error.


Pricing

Google-SERP-SEO-Scraper uses simple, pay-per-result pricing. There are no subscriptions and no hidden fees — you only pay for what you scrape.

PricingFreeStarterScaleBusiness
Discount tierNo discountBronze discountSilver discountGold discount
Scraped search result page (per 1,000)$5.00$5.00$5.00$5.00
Full SEO data (per run)$0.015$0.013$0.012$0.010
Actor start (per run)$0.001$0.0008$0.0007$0.0006
Platform usageFree ✅Free ✅Free ✅Free ✅

How the pricing works

Scraped search result page — $5.00 / 1,000 pages This is the core cost. You pay per search result page scraped, billed at a rate of $5.00 per 1,000 pages (i.e. $0.005 per page). Your discount tier doesn't change this rate — it's the same across all plans.

Full SEO data — charged once per run, not per page This is a flat, one-time fee applied once per Actor run, regardless of how many pages you scrape in that run. Whether you scrape 1 page or 10 pages in a single run, you only pay this fee one time — it does not multiply per page. The rate drops as your discount tier increases (from $0.015 down to $0.010).

Actor start — charged once per run Same principle as above: a small, flat fee for starting the Actor, charged once per run no matter how many pages are processed in that run.

Platform usage — always free Unlike most Actors on the platform, you are not charged for compute, memory, or platform usage. This is fully included at no extra cost across every tier — so your total cost is just the sum of the page-scraping fee plus the one-time per-run fees above.

Example

If you run the Actor once and scrape 10 pages on the Free tier:

  • Scraped pages: 10 × $0.005 = $0.05
  • Full SEO data (one-time, per run): $0.015
  • Actor start (one-time, per run): $0.001
  • Platform usage: $0.00
  • Total: $0.066

Note that scraping 1 page instead of 10 in that same run would still only cost $0.015 for SEO data and $0.001 for Actor start — those two fees don't scale with page count.

🔑 SEO & Keyword Research Use Cases

  • Google SERP scraper for rank tracking and position monitoring
  • Keyword research API for search volume, difficulty, and click-value estimation
  • Competitor SEO analysis to reverse-engineer who's ranking and why
  • PPC & Google Ads intelligence to monitor competitor ad spend and creative
  • Content strategy research using "People Also Ask" and related search data

🔌 API & Integrations

This actor isn't limited to the Apify Console — every feature is available programmatically, so you can plug it into your own app, automation, or AI agent.

🌐 Apify API

Every actor on Apify runs behind a full REST API. Authenticate with a Bearer token and call it directly:

curl "https://api.apify.com/v2/acts/dxbear/Google-SERP-SEO-Scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
-X POST \
-H "Content-Type: application/json" \
-d '{ "query": "your keyword here" }'

This runs the actor and returns the dataset items directly in the response — ideal for short runs (under 5 minutes). For longer jobs, run asynchronously and poll the run status, or attach a webhook to get notified on completion.

📚 Resources:

🤖 MCP (Model Context Protocol) — Use This Actor as an AI Agent Tool

This actor can be exposed directly to AI agents and LLM-powered assistants (Claude, Cursor, VS Code, and any MCP-compatible client) via Apify's hosted MCP server. Once connected, your AI agent can discover this actor, understand its input schema automatically, run it, and read the results — no manual API wiring required.

Connect at mcp.apify.com using your Apify API token, then point any MCP client at it.

📚 Resources:

🔗 n8n Automation

Run this actor as a step in your n8n workflows — no code required. The official Apify node supports Run Actor, Run Task, and Get Dataset Items operations, and can feed results straight into Google Sheets, databases, Slack, or 1,000+ other n8n-connected apps.

Settings → Community Nodes → Install → @apify/n8n-nodes-apify

📚 Resources:

🧠 AI Agents & LLM Workflows

Beyond MCP, this actor's structured JSON output is built to be consumed directly by LLM pipelines and custom AI agents — feed the dataset into a RAG pipeline, use it as a tool call in a LangChain/LangGraph agent, or wire it into your own agent framework via the standard Apify API.

📚 Resources:


💬 Support

Questions, feature requests, or bug reports — reach out any time:


Built for SEO teams, marketers, and developers who need real Google data — not guesswork. ⭐ If this actor saves you time, consider leaving a rating on the Apify Store.