Google News Scraper: Articles by Keyword, Topic & Country
Pricing
from $1.00 / 1,000 articles
Google News Scraper: Articles by Keyword, Topic & Country
Scrape Google News articles by keyword or topic in any of 84 regions and languages: title, publisher name and site, date, Google News link, the publisher's article URL on request, and related coverage. Time filters (1 hour to 1 year), several keywords per run, past 100 per keyword. Misses free.
Pricing
from $1.00 / 1,000 articles
Rating
0.0
(0)
Developer
Hyperbach
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Google News articles, logged out: search keywords or Google News topics in, one row per article out — the title, the publisher's name and site, the date published, the Google News link, the publisher's own article URL on request, and the other articles Google lists on the same story — in any of 84 regions and languages, with a time frame from the last hour to the last year, several keywords in one run, and past Google's 100 a feed one day at a time. One free row per keyword or topic carries a completeness verdict: COMPLETE (the feed's own end), CAPPED (your limit), TRUNCATED (Google holds more than its feeds serve) or PARTIAL. No login, no API key, no browser, proxies handled for you.
$4.00 per 1,000 article rows on the Free plan, $3.40 on Starter. A run start is $0.002. The default input returns about 50 rows for about $0.202. A value that names nothing is a free row that says why.
Why this Google News scraper
- Keywords and topics, any edition. Give search words (
bitcoin,"electric vehicles" OR EV,tesla site:reuters.com) and Google News sections (WORLD,BUSINESS,TECHNOLOGY…TOP_STORIES) or a topic or section URL copied from news.google.com. Pick one of 84 Google News editions (US:en,GB:en,DE:de,FR:fr,JP:ja,BR:pt-419…); a topic URL is read in its own edition. - Time filters.
timeframe=1h,1d,7d,30dor1ykeeps a keyword's articles in the last hour, day, week, month or year; Google's ownafter:YYYY-MM-DDandbefore:YYYY-MM-DDin a keyword set your own dates. Schedule1hruns for hourly monitoring. - Past Google's 100. Google's feed serves about 100 articles a keyword. With a larger
maxArticles(or 0) the run reads the keyword one day at a time, newest day first, back to the time frame's start: on our test eight days of "artificial intelligence" gave 777 distinct articles where the feed gave 100 (2026-10-29). A day that Google fills to its own limit makes the verdict TRUNCATED, so you know when more exist. - The publisher's URL, on request. Every row has the publisher's name and site and the Google News link;
decodeUrlsadds the publisher's own article URL (url), resolved from Google's link without a browser (100 of 100 on our deployed test, 2026-10-29; two more requests an article, so 100 articles take about 30 s instead of 2). The same price either way. - The story's other coverage. When Google groups several articles into one story,
related_articleslists the others (title, publisher, link): one row, the whole cluster. - Honest runs. A keyword with no article is a free
no_resultsrow (two exits agreed), an unknown topic a freenot_foundrow, a value that is not a keyword or topic a freeinvalidrow, a repeated value a freeduplicaterow. Every input gets a row with its verdict; an article two keywords list is charged once. - Fast and light. Plain HTTP on Google News' own RSS feeds: about 0.3 KB an article on the wire, 100 articles a call. On our deployed test 100 articles of one keyword took 1.4 s of reading, 4.7 s in all (2026-10-29).
Who it's for
- PR, brand and communications teams — every article that names a brand, a client or a person, read every hour or day with
1h/1d, the publisher and the date on each row, into a sheet, Slack or a dashboard. - Analysts, traders and researchers — the coverage of a company, a market or a topic over days or months (
after:/before:or a time frame past the feed's 100), with each article's publisher and date and the story clusters Google built. - Data and AI teams — typed rows keyed by
article_id, the publisher's article URL for a later crawl (decodeUrls), a free row per keyword with the verdict and a run summary to check a pipeline against.
Quick start
The 50 newest articles about bitcoin
{"keywords": ["bitcoin"],"maxArticles": 50}
Three keywords in the last 24 hours, with the publishers' URLs
{"keywords": ["tesla","spacex","nvidia"],"timeframe": "1d","maxArticles": 20,"decodeUrls": true}
German business and technology news
{"topics": ["BUSINESS","TECHNOLOGY"],"regionLanguage": "DE:de"}
Every article of a week, past the feed's 100
{"keywords": ["artificial intelligence"],"timeframe": "7d","maxArticles": 0}
Output
One row per article (and one free row per keyword or topic):
| field | meaning |
|---|---|
row_type | article (one article, charged) or input (the keyword's or topic's row with the walk's verdict; free). |
input_index | The 1-based position of the input in its list (keywords or topics). |
input_value | The keyword or topic as you gave it. |
input_kind | What the input is: keyword, topic, top_stories, topic_url, invalid or duplicate. |
status | An input row: ok, no_results, not_found, invalid, duplicate, failed or not_read (see the FAQ). An article row: ok. |
status_detail | Why, in words, when the status is not ok. |
scraped_at | When the row was read (ISO 8601, UTC). |
position | The article's place among this input's delivered articles (1 = first). |
title | The article's headline, without the publisher's name Google appends. |
source_name | The publisher's name, as Google News shows it. |
source_url | The publisher's site (its home page). |
published_at | When the article was published (ISO 8601, UTC). |
url | The publisher's own article URL, when decodeUrls is on (see url_status). |
url_status | decoded (url holds the publisher's URL), not_asked (decodeUrls off) or failed (Google did not resolve this link). |
google_news_url | The article's Google News link (it leads to the publisher's article). |
article_id | Google News' id of the article (the key: one row per id a run). |
related_articles | The other articles Google lists on the same story: one object per article with title, source_name and google_news_url (empty when the story has one article). |
related_count | How many articles related_articles holds. |
feed_position | The article's place in the Google News feed it came from. |
window | The day (YYYY-MM-DD) whose feed gave the article, when the run read past the first feed one day at a time; empty for the first feed. |
first_seen_at | With onlyNew: the day this memory first saw the article. |
last_seen_at | With onlyNew: the day this memory last saw the article. |
times_seen | With onlyNew: how many runs of this memory saw the article. |
region_language | The Google News edition read (US:en …). |
timeframe | A keyword's time frame (all, 1h, 1d, 7d, 30d, 1y); empty for a topic. |
feed_url | An input row: the Google News feed the input's first call read. |
articles_delivered | An input row: the article rows delivered for this input. |
feeds_read | An input row: how many feeds were read (the first feed and the day windows). |
skipped_seen | An input row, with onlyNew: articles an earlier run of this memory delivered, skipped free (not decoded, no cap slot taken). |
verdict | An input row: COMPLETE (the feed's own end, or every day of the time frame read), CAPPED (your cap), TRUNCATED (Google held more than its feeds serve) or PARTIAL (a refusal or the time limit). |
verdict_detail | An input row: the verdict in words — articles delivered, feeds and day windows read, articles skipped, why the walk stopped. |
Example record:
{"row_type": "article","input_index": 1,"input_value": "climate change","input_kind": "keyword","status": "ok","status_detail": null,"scraped_at": "2026-10-29T10:45:09Z","position": 3,"title": "Climate change should be declared 'global health emergency' as health harms and heat deaths accelerate","source_name": "DW.com","source_url": "https://www.dw.com","published_at": "2026-10-28T05:54:44Z","url": "https://www.dw.com/en/experts-urge-global-health-emergency-as-climate-harms-accelerate/a-79773232","url_status": "decoded","google_news_url": "https://news.google.com/rss/articles/CBMingFBVV95cUxNZ2JpQmRMQzVMQW1SdG1vdTFzZFZTVWdIN3A4ZUhDczhUeUpSY2lGSFc3b01LY043T3R1R1BRZDFyQkFQZ2RIakFPenVjd1RoSmFJdlp1YU5CZ3BMa1VfaHV6N2RISl9IeFRQNDhCU3pWVWlDc1NZM3Bxd3phamxQTThPb2pJSUdVN3ZkTUxWNnE1Q0Nwdm1qM19uNEpXZ9IBngFBVV95cUxOVTc0czlZQWZUQ3VKbGhHUHBYUk82aGV2aXNqVXNKMU9rRXV2ODYyV3NmMGE3MkNWNWgzZkxGajh3dHNGQUl1NHd4N203TWJqdThIejFxS2xvX1NTLVdXcTdXQ0RTcUtucm9wS1dQelUtOVZoRlhmZVpRbkhSNXAyM1Byb29SZlJ6dlVqWk1Jakx4ZmtzWkZ6T2QyTFpZdw?oc=5","article_id": "CBMingFBVV95cUxNZ2JpQmRMQzVMQW1SdG1vdTFzZFZTVWdIN3A4ZUhDczhUeUpSY2lGSFc3b01LY043T3R1R1BRZDFyQkFQZ2RIakFPenVjd1RoSmFJdlp1YU5CZ3BMa1VfaHV6N2RISl9IeFRQNDhCU3pWVWlDc1NZM3Bxd3phamxQTThPb2pJSUdVN3ZkTUxWNnE1Q0Nwdm1qM19uNEpXZ9IBngFBVV95cUxOVTc0czlZQWZUQ3VKbGhHUHBYUk82aGV2aXNqVXNKMU9rRXV2ODYyV3NmMGE3MkNWNWgzZkxGajh3dHNGQUl1NHd4N203TWJqdThIejFxS2xvX1NTLVdXcTdXQ0RTcUtucm9wS1dQelUtOVZoRlhmZVpRbkhSNXAyM1Byb29SZlJ6dlVqWk1Jakx4ZmtzWkZ6T2QyTFpZdw","related_articles": [{"title": "Climate change is a 'global health emergency' and the harms are accelerating, Lancet report warns","source_name": "ABC News - Breaking News, Latest News and Videos","google_news_url": "https://news.google.com/rss/articles/CBMiqgFBVV95cUxNR0RmVVk5R0R1SlZ5bmxUd0kzbW43UDl0ckZYMUprTl9aMzZ3Mzl1NkM5bUdaUTlkMk51eUludThnbFAydUFfekFtMUcwT2pjVUVGS1YtN1JKS0ZGMjRJMUVOTzJna2ZzOXJIb2NHRE9YMmlUSXI0ZTRRaWlMeGxCa2dPdGNzZGFCUWVqRmR5aHBuU1hRc2VCc0FpUnFwRGVmM2lCRnJBaXNUUdIBrwFBVV95cUxOQVdGZGZhNXpYX1dYYVJkWVpEVXQ3cUF3aVF0TDhLQWJCZU9zWHhBb0dIa2NMTk5SWC1fem9OV3FBVWI2VjI1eEJ5SFhjZEtLano0TzlWT1hxVFpqYlNvbF9lNnpfQV9pNGpud1VjNWRsb2JyR3c1M1hGdTY5bnZsWjljUmlWcnQ1eDJ1NDdUNjh6VEFyUUNlcVdBZk14YXFNTDdVT2p2YmR6QlVwT3VF?oc=5"},{"title": "Why the WHO must declare climate change a public health emergency","source_name": "Phys.org","google_news_url": "https://news.google.com/rss/articles/CBMidkFVX3lxTE9LUDFSY2RCWFpZdFZFWm02SXVPYkJXYTlqbWgzOG52NmpQUGlYbkdNRWhEaHhHY2xKWXFqdkNza09HeDA2Z3NyTVNObHNIOS1jSFRNZWw5Nml1UjNLbzZDTjRyV3QyZGY3QWkybWoxNF8xS2ZKQXc?oc=5"}],"related_count": 2,"feed_position": 3,"window": null,"first_seen_at": null,"last_seen_at": null,"times_seen": null,"region_language": "US:en","timeframe": "all","feed_url": null,"articles_delivered": null,"feeds_read": null,"skipped_seen": null,"verdict": null,"verdict_detail": null}
Pricing
Pay for the articles a run delivers, plus one run start; no platform usage is billed to you. The article price falls with your Apify plan.
| event | unit | Free | Starter | Scale | Business |
|---|---|---|---|---|---|
Article (article) | per 1,000 | $4.00 | $3.40 | $2.80 | $1.00 |
Run start (start) | per run | $0.002 | $0.002 | $0.002 | $0.002 |
An article is $4.00 per 1,000 on the Free plan ($0.004 an article), with or without the decoded publisher URL. Each run that delivers a charged article also pays the run start, $0.002 once; a run that delivers no charged article pays nothing at all. So 100 articles of one keyword cost $0.402 on the Free plan; several keywords in one run share one start. The free row of every keyword and topic, a keyword with no article (no_results), an unknown topic (not_found), a value that is not a keyword or topic (invalid), a repeated value (duplicate), a value left at the charge limit or the time limit (not_read) and a refusal the run could not pass (failed) are never charged. An article is charged once a run, even when two keywords list it. A run that stops early (a timeout, an abort) is charged for the articles it delivered. maxItems counts the charged rows; before the first request the log names the price of each row at your plan and the most the run can cost. Enterprise plans have their own rates: the Actor's Pricing tab shows the price for your plan.
Usage patterns
- A schedule — Save a task with
onlyNew(and astateStoreNameto name the memory), settimeframeto the task's interval (1hfor an hourly task,1dfor a daily one) and schedule it. The first run delivers the articles of its feeds; each later run delivers only the articles an earlier run of that memory did not, and skips the rest free, undecoded — the input row counts them inskipped_seen. A skipped article takes nomaxArticlesslot: with a time frame wider than the schedule and a full feed, the walk reads the day windows for articles the memory never received. Every delivered row of a monitored run carriesfirst_seen_at,last_seen_atandtimes_seen. Two tasks with the same memory name share what they delivered; without a name, the memory is derived from the keywords, topics and edition, so the same inputs find the same memory. - Keywords and topics —
keywordstakes search words, one search per line; Google's operators work inside a line (site:,OR,-word, quotes,when:,after:,before:).topicstakes the section namesWORLD,NATION,BUSINESS,TECHNOLOGY,ENTERTAINMENT,SPORTS,SCIENCE,HEALTH,TOP_STORIES, or a topic or section URL from news.google.com (open a topic in your browser and copy its address). - What a row is —
row_type=article: one article with its record;related_articlesholds one object per other article of the same story.row_type=input: the free row of one keyword or topic —articles_delivered,feeds_read,feed_url, theverdictwith itsverdict_detail, and thestatuswith its reason. - How far a keyword goes —
maxArticles= 100 (the default) reads one feed: about the 100 articles Google ranks first in the time frame. A larger number, or 0, reads one day at a time after a full feed, newest day first, back to the start oftimeframe(7d,30d,1y;alluntil 60 empty days in a row);1hand1dare one feed. A topic's feed is its own list (about 40-70 articles).maxItemscaps the charged rows of the whole run. The input row'sverdictsays where the walk stopped and why.
Input configuration
| field | type | default | what it does |
|---|---|---|---|
keywords | array | Search words, one search per line (bitcoin, artificial intelligence, "electric vehicles" OR EV). Google's own operators work: site:reuters.com, OR, -word, quotes, and when:, after:YYYY-MM-DD, before:YYYY-MM-DD for your own dates (then timeframe is not added to that line). Up to 1,000 keywords and topics a run. A line given twice gets a free duplicate row. | |
topics | array | Google News sections: WORLD, NATION, BUSINESS, TECHNOLOGY, ENTERTAINMENT, SPORTS, SCIENCE, HEALTH, TOP_STORIES (the front page), or a topic or section URL copied from news.google.com (https://news.google.com/topics/…, read in the URL's own region and language). A topic's feed is its own list (about 40-70 articles); timeframe does not apply to it. | |
regionLanguage | US:en / SK:sk / AU:en / BW:en / CA:en / ET:en / GH:en / IN:en / ID:en / IE:en / IL:en / KE:en / LV:en / MY:en / NA:en / NZ:en / NG:en / PK:en / PH:en / SG:en / ZA:en / TZ:en / UG:en / GB:en / ZW:en / ID:id / CZ:cs / DE:de / AT:de / CH:de / AR:es-419 / CL:es-419 / CO:es-419 / CU:es-419 / ES:es / US:es-419 / MX:es-419 / PE:es-419 / VE:es-419 / BE:fr / CA:fr / FR:fr / MA:fr / SN:fr / CH:fr / IT:it / LV:lv / LT:lt / HU:hu / BE:nl / NL:nl / NO:no / PL:pl / BR:pt-419 / PT:pt-150 / RO:ro / SI:sl / SE:sv / VN:vi / TR:tr / GR:el / BG:bg / RU:ru / UA:ru / RS:sr / UA:uk / IL:he / AE:ar / SA:ar / LB:ar / EG:ar / IN:mr / IN:hi / BD:bn / IN:bn / IN:ta / IN:te / IN:ml / TH:th / CN:zh-Hans / TW:zh-Hant / HK:zh-Hant / JP:ja / KR:ko | "US:en" | The Google News edition to read: country and language, as Google names it (US:en is the United States in English, DE:de Germany in German, BR:pt-419 Brazil in Portuguese). |
timeframe | all / 1h / 1d / 7d / 30d / 1y | "all" | How recent the keywords' articles are: all (any time; Google's own mix, newest first), 1h, 1d, 7d, 30d or 1y (the last hour, day, week, month, year). For hourly monitoring take 1h on a schedule. |
maxArticles | integer | 100 | Stop each keyword or topic at this many articles (0 = every article the feeds serve). Google's feed serves about 100 a keyword; past that the run reads one day at a time, newest day first, back to the time frame's start (all: until 60 empty days in a row). |
decodeUrls | boolean | false | Resolve each article's Google News link to the publisher's own article URL (url; two more requests an article, so a run takes longer). Off: url stays empty and google_news_url leads to the article through Google. The price is the same. |
onlyNew | boolean | false | Remember every article delivered under this memory (stateStoreName, or a name derived from the inputs) and skip it free in the next run: a scheduled task delivers only what is new. The input row counts the skipped (skipped_seen). |
stateStoreName | string | "" | The name of the onlyNew memory, so several tasks can share one or keep theirs apart. Empty: a name derived from the inputs. |
maxItems | integer | 0 | Stop the run after this many article rows across every keyword and topic (0 = no limit). Input rows are free and not counted; a keyword or topic left unread at the cap gets a free not_read row. |
Errors
A run does not fail because of your input. When an input cannot be used — a date that is not a date, an id in the wrong form, two settings that contradict each other — the run ends Succeeded, charges nothing, and says what to change:
- the status message starts with
INPUT REJECTED; - the dataset holds one row,
{"error": true, "code": "…", "message": "…"}, and no results; - the key-value store record
ERRORholds the same object.
From code, check error on the first row before reading results.
A keyword with no article is not an error: it gets one free row with status = no_results (two exits agreed), and the run goes on with the others. A run that ends Failed is a fault on our side, never your input; it charges nothing, and we are alerted.
FAQ
Does it give the article's text, snippet or image?
No. Google News' feeds carry the title, the publisher, the date and the link, not a snippet or an image, and the article's text is on the publisher's site. Turn on decodeUrls to get each publisher's article URL for your own crawl.
Why is url empty?
url (the publisher's own article URL) is filled when decodeUrls is on; url_status says decoded, not_asked (off) or failed (Google did not resolve that link; the row keeps its google_news_url, which still leads to the article).
Which status is which?
An input row's status is ok (articles served), no_results (Google lists no article for the keyword; two exits agreed), not_found (no such topic; two exits agreed), invalid (a value that is not a keyword, a section name or a news.google.com topic URL), duplicate (the same value again: read once), failed (a refusal or an error; free) or not_read (left at maxItems, the charge limit or the run's time limit). An article row's status is ok.
Does it need a Google account or API key?
No. Everything is read from Google News' public feeds, logged out.
Integration
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('hyperbach/google-news-scraper').call({"keywords": ["bitcoin"], "maxArticles": 50});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Python
from apify_client import ApifyClientclient = ApifyClient('YOUR_TOKEN')run = client.actor('hyperbach/google-news-scraper').call(run_input={'keywords': ['bitcoin'], 'maxArticles': 50})items = client.dataset(run['defaultDatasetId']).list_items().items
CLI
$apify call hyperbach/google-news-scraper --input '{"keywords": ["bitcoin"], "maxArticles": 50}'
REST
curl -X POST "https://api.apify.com/v2/acts/hyperbach~google-news-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H 'Content-Type: application/json' -d '{"keywords": ["bitcoin"], "maxArticles": 50}'
AI agents and MCP
Apify's MCP server offers this Actor as a tool to Claude, Cursor, VS Code and any other MCP client. Connect https://mcp.apify.com?tools=hyperbach/google-news-scraper and ask, for example: "Get the 50 newest Google News articles about bitcoin". The agent fills the input from the table above and reads the rows from the run's dataset. The input names are the ones in the table above.
n8n, Make and Zapier
The Apify node in n8n, the Apify app in Make and the Apify integration in Zapier run this Actor on a schedule or from a trigger and read its dataset. A webhook on the run's end (Integrations on the Actor page) sends the rows on to your own endpoint. Nothing to install on our side.
Support
Disagree with a charge? Write to apify@hyperbach.com with the run ID. We will ask Apify to compensate you, and the charge comes back to your Apify account as platform credit.
Did it do the job? A short review on the Store, at any rating, helps the next buyer choose.
See also
- ChatGPT Scraper — what ChatGPT, Gemini, Perplexity and Google's AI Mode and AI Overviews answer for your queries, with every source they cite.
- Substack Scraper — the posts of a Substack newsletter with the full text of free posts, the date, the paywall flag and the likes.
- Yahoo Finance Scraper — Yahoo Finance quotes, statistics, company profiles and price history by ticker, for stocks, ETFs, indices, crypto and FX.
This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.