# Google News Scraper - Real Article Links, Alerts (`dottti/google-news`) Actor

Google News articles by keyword, topic or top stories, any country and language incl. Arabic. Real publisher URLs, publish time, source, optional page metadata (author, image, description) and a new-articles-only alert mode. Status row per feed; failed links are free.

- **URL**: https://apify.com/dottti/google-news.md
- **Developed by:** [Dottti](https://apify.com/dottti) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 articles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google News Scraper: Real Article Links, Alerts

Get news articles from Google News by keyword, by topic or from the top stories of any country. Each article comes with its headline, publisher, publish time and the **real publisher URL**, decoded from the news.google.com link. Arabic editions (Saudi Arabia, UAE, Egypt and more) work the same way as English ones.

Turn on page details to also get each article's description, authors, main image, language, section and keywords from the publisher's own page. Turn on alert mode to get only articles you have not received before.

You need no Google account and no API key.

### Who uses it

- **PR and communications teams** who track mentions of a company, a minister or a product.
- **Market and investment analysts** who follow news on companies, sectors and countries.
- **Media monitoring services** who need clean, deduplicated article lists in many languages.
- **AI and data pipelines** that need real article URLs to fetch and summarize.
- **Researchers** who collect coverage of an event across countries and languages.

### What you can do

- **Search** with any keywords. Google's search operators work: `"exact phrase"`, `OR`, `-word`, `site:reuters.com`, `intitle:word`, `when:1d`, `after:2026-10-01`, `before:2026-10-15`.
- **Read topic feeds**: WORLD, NATION, BUSINESS, TECHNOLOGY, ENTERTAINMENT, SPORTS, SCIENCE, HEALTH, or any topic link from news.google.com.
- **Read top stories** of each edition, with the cluster of other outlets that cover the same story.
- **Pick countries and languages**: `US:en`, `GB:en`, `SA:ar`, `AE:ar`, `AE:en`, `EG:ar`, `IN:en`, `FR:fr` and any other Google News edition. Every query runs in every edition you list.
- **Limit by time**: past hour, 12 hours, day, week, 30 days or year, or a date range.
- **Remove duplicates**: an article found by two queries or two editions is delivered and charged once.
- **Alert mode**: on a schedule, each run returns only articles that earlier runs did not return.

### Input examples

The latest news on two companies in the US edition:

```json
{
  "queries": ["Saudi Aramco", "Nvidia earnings"],
  "editions": ["US:en"],
  "timeWindow": "7d",
  "maxArticlesPerQuery": 30
}
```

Arabic news from three Gulf and Egyptian editions, with page details:

```json
{
  "queries": ["أرامكو", "رؤية 2030"],
  "editions": ["SA:ar", "AE:ar", "EG:ar"],
  "timeWindow": "1d",
  "maxArticlesPerQuery": 50,
  "includeArticleDetails": true
}
```

Business and technology topics plus top stories, as an hourly alert:

```json
{
  "topics": ["BUSINESS", "TECHNOLOGY"],
  "includeTopStories": true,
  "editions": ["SA:ar", "US:en"],
  "timeWindow": "1d",
  "maxArticlesPerQuery": 100,
  "onlyNew": true,
  "stateName": "gulf-business-alert"
}
```

Only one site's coverage of a subject:

```json
{
  "queries": ["site:reuters.com Saudi Arabia"],
  "editions": ["US:en"],
  "maxArticlesPerQuery": 100
}
```

### Output

Every row has a `type` field.

| type | One row is | Charged |
|---|---|---|
| `article` | One news article | Yes, when its real URL was found (or when decoding is off) |
| `status` | One feed (query, topic or top stories, per edition) and what happened to it | No |

#### Article row (real output, 2026-10-28, link shortened)

```json
{
  "type": "article",
  "title": "وزارة الداخلية السعودية تعزز توطين الصناعات العسكرية ضمن رؤية 2030",
  "publisherName": "معلومات مباشر",
  "publisherUrl": "https://www.mubasher.info",
  "articleUrl": "https://www.mubasher.info/news/4691667/...",
  "ampUrl": null,
  "googleNewsUrl": "https://news.google.com/rss/articles/CBMiiwRBVV95cUxQeDlu...?oc=5",
  "googleNewsId": "CBMiiwRBVV95cUxQeDlu...",
  "publishedAt": "2026-10-27T20:22:49.000Z",
  "snippet": null,
  "feed": "search",
  "query": "رؤية 2030",
  "topic": null,
  "country": "SA",
  "language": "ar",
  "edition": "SA:ar",
  "position": 1,
  "urlDecoded": true,
  "decodeError": null,
  "relatedArticles": [],
  "scrapedAt": "2026-10-28T08:49:46.536Z"
}
```

`snippet` is `null` for most articles. Google News feeds carry only the headline and the source name. Turn on page details to get the publisher's own description.

#### Article row with page details (real output, 2026-10-28, links shortened)

```json
{
  "type": "article",
  "title": "الذكاء الاصطناعي يعزز كفاءة التسويق العقاري في دبي",
  "publisherName": "البيان",
  "publisherUrl": "https://www.albayan.ae",
  "articleUrl": "https://www.albayan.ae/economy/1560908",
  "publishedAt": "2026-10-27T13:10:00.000Z",
  "query": "دبي",
  "edition": "AE:ar",
  "urlDecoded": true,
  "pageTitle": "الذكاء الاصطناعي يعزز كفاءة التسويق العقاري في دبي",
  "pageDescription": "يشهد القطاع العقاري في دبي توسعاً متسارعاً في حجم المشاريع والعروض الاستثمارية، ما يرفع من أهمية الوصول السريع والدقيق إ",
  "pagePublishedAt": "2026-10-27T13:10:00.000Z",
  "pageModifiedAt": "2026-10-27T13:26:56.000Z",
  "pageAuthors": ["البيان"],
  "pageImage": "https://www.albayan.ae/assets/images/2026/10/27/5385096.jpeg",
  "pageLanguage": "ar",
  "pageSiteName": "البيان",
  "pageSection": "اقتصاد",
  "pageCanonicalUrl": "https://www.albayan.ae/economy/1560908",
  "detailsStatus": "ok",
  "detailsError": null
}
```

Page fields come from the page's meta tags, Open Graph tags and JSON-LD. A field is `null` (or an empty list) when the page does not publish it. When a page gives a time with no time zone, `pagePublishedAt` keeps it as written, without a `Z`.

#### Top story with related coverage (real output, 2026-10-28, shortened)

```json
{
  "type": "article",
  "title": "VCs will make billions on Anthropic’s IPO, but Amazon is set to make much (much) more",
  "publisherName": "TechCrunch",
  "articleUrl": "https://techcrunch.com/2026/10/27/vcs-will-make-billions-on-anthropics-ipo-but-amazon-is-set-to-make-much-much-more/",
  "publishedAt": "2026-10-28T01:15:28.000Z",
  "feed": "topic",
  "topic": "BUSINESS",
  "edition": "US:en",
  "relatedArticles": [
    { "title": "Chart: Anthropic's cash pile towers over nearly every U.S. company", "publisherName": "CNBC", "googleNewsUrl": "https://news.google.com/rss/articles/CBMidkFV...", "googleNewsId": "CBMidkFV..." }
  ]
}
```

Related articles carry the Google News link only. Their real URLs are not decoded, so they cost nothing.

#### Status row (real output, 2026-10-28)

```json
{
  "type": "status",
  "feed": "search",
  "query": "Saudi Aramco",
  "searchedAs": "Saudi Aramco when:7d",
  "topic": null,
  "edition": "US:en",
  "country": "US",
  "language": "en",
  "status": "ok",
  "articlesInFeed": 100,
  "inTimeRange": 100,
  "duplicates": 0,
  "alreadySeen": 0,
  "delivered": 30,
  "undecoded": 0,
  "detailsOk": 0,
  "detailsFailed": 0,
  "error": null,
  "charged": false
}
```

Status values: `ok`, `partial` (some links not decoded), `undecoded`, `no_results`, `not_found`, `blocked`, `cut_by_cost_limit`, `skipped_cost_limit`.

The run also saves a `RUN_SUMMARY` record in the key-value store. It lists every feed, decode counts, requests, bytes and the proxy tier used.

### Alert mode

1. Set `onlyNew` to `true` and give the alert a `stateName`, for example `aramco-watch`.
2. Schedule the actor (Apify Console, Schedules, for example every hour).
3. The first run returns everything it finds and remembers it. Each later run returns only articles that no earlier run returned.

The actor matches articles by Google News id, by real URL and by headline plus publisher. It saves the list in a key-value store named `google-news-state`. Entries older than 45 days are dropped. Articles held back by your cost limit are not remembered, so they come back in the next run.

For alerts, set `maxArticlesPerQuery` to 100. A feed holds at most about 100 articles, so this lets the first run see the whole feed.

### How to schedule

In Apify Console open the actor, save your input as a task, then open **Schedules** and add the task. Use alert mode for scheduled runs, so you pay only for articles you have not seen. You can send results to email, Slack, Google Sheets or a webhook with Apify integrations.

### Pricing

You pay per result. Platform usage is included in the price.

| Event | Price |
|---|---|
| Article delivered with its real URL | $1.00 per 1,000 |
| Article page details read (only when the page was read) | $0.50 per 1,000 |

Free of charge:

- Status rows.
- Articles whose real URL Google would not give. They are delivered with `urlDecoded: false`.
- Duplicates and, in alert mode, articles you already received.

With "Get the real article URL" turned off, every article row is charged and `articleUrl` is `null`.

Set a cost limit on the run to cap spending. The actor stops cleanly at the limit and the status rows say which feeds were cut.

### Limits

- A Google News feed holds up to about 100 articles. For more, split the work by date range (`after:` and `before:`) or by `site:`.
- Search feeds sort by relevance. Topic and top-story feeds sort by Google's own ranking. Use `timeWindow` to keep only recent articles.
- Decoding needs two requests per article. A run of 1,000 articles takes about 10 to 15 minutes.
- Some publisher sites block automated page reads. Those articles keep their Google data, get `detailsStatus: "blocked"` and are not charged for details. After two refusals from one site, the actor skips the rest of that site's pages in the run.
- `snippet` is usually `null`, because Google News feeds carry no article text.
- The actor reads public pages only. It does not log in and does not read paywalled text.

# Actor input Schema

## `queries` (type: `array`):

Keywords to search on Google News. Google search operators work: "exact phrase", OR, -exclude, site:reuters.com, intitle:word, when:1d, after:2026-10-01, before:2026-10-15. Arabic queries work too, for example أرامكو.

## `topics` (type: `array`):

Topic feeds. Use a section name (WORLD, NATION, BUSINESS, TECHNOLOGY, ENTERTAINMENT, SPORTS, SCIENCE, HEALTH), a topic id (CAAq...) or a news.google.com/topics/... link.

## `includeTopStories` (type: `boolean`):

Also read the Top stories feed (the Google News home page) of each edition.

## `editions` (type: `array`):

One Google News edition per entry, written COUNTRY:language. Examples: US:en, GB:en, SA:ar (Saudi Arabia, Arabic), AE:ar, AE:en, EG:ar, IN:en, FR:fr, DE:de. Every query and topic runs in every edition.

## `timeWindow` (type: `string`):

Only articles published in this window. For searches it is sent to Google as when:; topic and top-story feeds are filtered by publish time. Ignored when a date range is set.

## `dateFrom` (type: `string`):

YYYY-MM-DD. Sent to Google as after: for searches.

## `dateTo` (type: `string`):

YYYY-MM-DD, inclusive. Sent to Google as before: for searches.

## `maxArticlesPerQuery` (type: `integer`):

Per query, topic or top-stories feed, per edition. Google News feeds hold up to 100 articles. For more, split by date range or by site:.

## `decodeUrls` (type: `boolean`):

Turns each news.google.com link into the publisher's own URL. Articles whose link Google will not decode are delivered free. Turn off for headlines only; every row is then charged.

## `includeArticleDetails` (type: `boolean`):

Opens each publisher page to read its description, publish and update time, authors, main image, language, site name, section and keywords. Charged as an extra event, only when the page was read.

## `includeRelated` (type: `boolean`):

Topic and top-story articles often come with a cluster of other outlets covering the same story. Adds them as relatedArticles (headline, outlet, Google News link).

## `dedupe` (type: `boolean`):

The same article found by two queries or two editions is delivered and charged once.

## `onlyNew` (type: `boolean`):

Delivers only articles that earlier runs with the same state name did not deliver. Use it on a schedule. The first run delivers everything it finds.

## `stateName` (type: `string`):

Name of the saved list of seen articles. Use a different name for each separate alert.

## `proxyConfiguration` (type: `object`):

Leave empty: the actor starts without a proxy and moves to Apify datacenter, then residential proxies only if Google blocks it. Set your own proxy to use only that.

## `autoProxyFallback` (type: `boolean`):

Move to Apify proxies when Google blocks requests.

## `allowResidentialFallback` (type: `boolean`):

Allow the last step of the fallback to use residential proxies.

## `maxConcurrency` (type: `integer`):

How many feeds and link decodes run at the same time. Keep it low; Google limits fast clients.

## Actor input object example

```json
{
  "queries": [
    "Saudi Aramco",
    "artificial intelligence"
  ],
  "includeTopStories": false,
  "editions": [
    "US:en"
  ],
  "timeWindow": "",
  "maxArticlesPerQuery": 20,
  "decodeUrls": true,
  "includeArticleDetails": false,
  "includeRelated": true,
  "dedupe": true,
  "onlyNew": false,
  "stateName": "default",
  "autoProxyFallback": true,
  "allowResidentialFallback": true,
  "maxConcurrency": 2
}
```

# Actor output Schema

## `results` (type: `string`):

All rows. Filter by the type field.

## `runSummary` (type: `string`):

Status per feed, decode counts, requests, bytes, retries and proxy tier used.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "Saudi Aramco",
        "artificial intelligence"
    ],
    "editions": [
        "US:en"
    ],
    "maxArticlesPerQuery": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("dottti/google-news").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": [
        "Saudi Aramco",
        "artificial intelligence",
    ],
    "editions": ["US:en"],
    "maxArticlesPerQuery": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("dottti/google-news").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "Saudi Aramco",
    "artificial intelligence"
  ],
  "editions": [
    "US:en"
  ],
  "maxArticlesPerQuery": 20
}' |
apify call dottti/google-news --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dottti/google-news"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/cxsddruHiRnbeyZjw/builds/I1RNtNPK1HFyFZrsH/openapi.json
