by lewisdonovan
Lightweight scraper for Google News
# Add to your Claude Code skills
git clone https://github.com/lewisdonovan/google-news-scraperGuides for using mcp servers skills like google-news-scraper.
Last scanned: 10/16/2026
{
"issues": [
{
"type": "npm-audit",
"message": "@istanbuljs/load-nyc-config: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "@jest/console: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@jest/core: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@jest/environment: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@jest/expect: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@jest/fake-timers: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@jest/globals: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@jest/reporters: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@jest/test-result: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@jest/test-sequencer: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@jest/transform: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@puppeteer/browsers: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@semantic-release/changelog: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@semantic-release/commit-analyzer: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@semantic-release/git: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@semantic-release/github: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@semantic-release/npm: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "@semantic-release/release-notes-generator: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "argparse: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "babel-jest: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "babel-plugin-istanbul: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "basic-ftp: basic-ftp: Quadratic-time CPU denial of service in Client.list() Unix directory-listing parser (RE_LINE backtracking)",
"severity": "high"
},
{
"type": "npm-audit",
"message": "brace-expansion: brace-expansion: Quadratic-time expansion of the `{a},b}` rewrite causes CPU denial of service",
"severity": "high"
},
{
"type": "npm-audit",
"message": "braces: braces vulnerable to stack-exhaustion denial of service through deeply nested patterns",
"severity": "high"
},
{
"type": "npm-audit",
"message": "create-jest: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "del: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "expect: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "extract-zip: extract-zip unvalidated symlink path traversal",
"severity": "high"
},
{
"type": "npm-audit",
"message": "fast-glob: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "get-uri: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "globby: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "http-cache-semantics: http-cache-semantics max-stale handling can disclose cross-user cached responses",
"severity": "high"
},
{
"type": "npm-audit",
"message": "ip-address: ip-address: Address6.isLinkLocal() recognizes fe80::/64 rather than fe80::/10, allowing SSRF and trust-boundary bypass to on-link hosts",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "jest: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-circus: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-cli: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-config: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-environment-node: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-haste-map: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-message-util: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-resolve: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-resolve-dependencies: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-runner: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-runtime: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-snapshot: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "jest-watcher: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "js-yaml: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "micromatch: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "pac-proxy-agent: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "postcss-selector-parser: PostCSS: Quadratic complexity in flat selector parsing allows CPU exhaustion",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "proxy-agent: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "puppeteer: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "puppeteer-core: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "rollup-plugin-delete: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "semantic-release: Vulnerability found",
"severity": "high"
},
{
"type": "npm-audit",
"message": "sprintf-js: sprintf-js vulnerable to denial of service through unbounded precision specifiers",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "undici: undici vulnerable to Denial of Service via unhandled error in WebSocket permessage-deflate decompression",
"severity": "high"
}
],
"status": "WARNING",
"scannedAt": "2026-10-16T08:46:26.324Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}See how google-news-scraper compares with popular alternatives.
google-news-scraper is an open-source mcp servers skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by lewisdonovan. Lightweight scraper for Google News. It has 382 GitHub stars.
google-news-scraper returned warnings in SkillsLLM's automated security scan. It has no critical vulnerabilities, but review the flagged issues in the Security Report section before adding it to your workflow.
Clone the repository with "git clone https://github.com/lewisdonovan/google-news-scraper" and add it to your Claude Code skills directory (see the Installation section above).
google-news-scraper is primarily written in JavaScript. It is open-source under lewisdonovan on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other MCP Servers skills you can browse and compare side by side. Open the MCP Servers category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh google-news-scraper against similar tools.
No comments yet. Be the first to share your thoughts!
Top skills in this category by stars
Requires a passing catalog security scan.
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
Get Google News results as JSON in one line of Node.js. Search any keyword, topic or the top stories, and get back titles, publisher links, sources and publish dates.
import googleNewsScraper from 'google-news-scraper';
const articles = await googleNewsScraper({ searchTerm: "OpenAI", timeframe: "1d" });
// [{ title: "...", link: "https://www.reuters.com/...", source: "Reuters", datetime: "2026-10-14T09:12:00.000Z", time: "3 hours ago", ... }]
hl/gl/ceid parameters to search local editions.getArticleContent to pull each article's body text, ready for summarisation or LLM pipelines.import and CommonJS require.Good for news monitoring, brand and competitor tracking, market research, trading signals, newsletters and feeding fresh context to AI agents.
🤖 Using an AI agent? There's an MCP server too, so Claude, Cursor and other MCP clients can search Google News directly: npx -y google-news-scraper-mcp.
SerpApi - The News Monitoring API. We help you access real-time search engine data via a simple API, which includes news from Google, Bing, and DuckDuckGo.
Want your product in front of developers building with news data? Sponsorship puts your logo here and on the npm page. Sponsor via GitHub Sponsors, or get in touch to talk about placements.
# Install via NPM
npm install google-news-scraper
# Install via Yarn
yarn add google-news-scraper
Simply import the package and pass a config object.
import googleNewsScraper from 'google-news-scraper';
// Search
const articles = await googleNewsScraper({ searchTerm: "The Oscars" });
// Top stories in the UK edition
const topStories = await googleNewsScraper({ queryVars: { hl: "en-GB", gl: "GB" } });
// A topic page
const tech = await googleNewsScraper({ baseUrl: "https://news.google.com/topics/CAAqJggKIiBDQkFTRWdvSUwyMHZNRGRqTVhZU0FtVnVHZ0pWVXlnQVAB" });
A minimum working example can be found in this repo. Full documentation on the config object can be found below.
The output is an array of JSON objects, with each article following the structure below:
[
{
"title": "Article title",
"link": "http://url-to-website.com/path/to/article",
"image": "",
"source": "Name of publication",
"sourceUrl": "https://url-to-website.com",
"datetime": "2024-05-13T08:02:22.000Z",
"time": "2 hours ago",
"articleType": "regular"
}
]
image is always an empty string, because Google News feeds don't include thumbnails. It's kept so code written for v2 doesn't break.
The config object passed to the function above has the following properties:
This is the search query you'd like to find articles for, simply pass the search string like so: searchTerm: "The Oscars".
The search term is no longer a required field, as hahagu added support for topic pages in #44. If searchTerm and baseUrl are both supplied, searchTerm wins. If neither is supplied, you get the Google News top stories.
The baseUrl property enables you to specify an alternate base URL for your search. This is useful when you want to scrape, for example, a specific Google news topic.
The scraper reads the RSS version of whatever page you pass, so https://news.google.com/topics/ABC is fetched as https://news.google.com/rss/topics/ABC. If neither searchTerm nor baseUrl is supplied, you get the top stories.
The URLs that Google News supplies for each article are "ugly" links (eg: "https://news.google.com/articles/CAIiEPgfWP_e7PfrSwLwvWeb5msqFwgEKg8IACoHCAowjuuKAzCWrzwwt4QY?hl=en-GB&gl=GB&ceid=GB%3Aen"), buy default the scraper will retrieve the actual "pretty" URL (eg: "https://www.nytimes.com/2020/01/22/movies/expanded-best-picture-oscar.html"). This takes two small requests to Google per article, run five at a time. To prevent this default behaviour and retrieve the "ugly" links instead, pass prettyURLs: false to the config object.
Credit to anthonyfranc for the base64 decode fix 🙏
Defaults to true.
The results can be filtered to articles published within a given timeframe prior to the request.
The format of the timeframe is a string comprised of a number, followed by a letter prepresenting the time operator. For example 1y would signify 1 year. Full list of operators below:
12h)7d)6m)1y)Defaults to 7d.
By default, the scraper does not return the article content, as this would require Puppeteer to navigate to each individual article in the results (increasing execution time significantly). If you would like to enable this behaviour, and receive the content of each article, simply pass getArticleContent: true, in the config. This will add two fields to each article in the output: content and favicon.
[
{
"title": "Article title",
"link": "https://url-to-website.com/path/to/article",
"image":"https://url-to-website.com/path/to/image.jpg",
"source": "Name of publication",
"time": "Time/date published (human-readable)",
"content": "The full text content of the article...",
"favicon": "https://url-to-website.com/path/to/favicon.png",
}
]
This is the only feature that needs a headless browser. Puppeteer is an optional dependency since v3, so install it yourself to use this feature:
npm install puppeteer
PLEASE NOTE: Due to the large amount of variable factors to take into account, this feature fails on many websites. All errors are handled gracefully and wil return an empty string as the content. Please ensure you handle such outcomes in your application.
Defaults to false
You can customise the log level to any of the following:
none: No logs will be output at all.error: Only errors will be outputted to the log.warn: Errors and warnings will be output to the log.info: Info, errors and warnings will be output to the log.verbose: All of the above and potentially more. Currently there are no specifically verbose logs, but in future I may move some of the info logs to verbose and/or add some debugging info there.Defaults to error.
An object of additional query params to add to the Google News URL string, formatted as key value pairs. This can be useful if you want to search for articles in a specific language, for example:
const articles = await googleNewsScraper({
searchTerm: "Últimas noticias en Madrid",
queryVars: {
gl:"ES",
ceid:"ES:es"
},
});
Defaults to null
Only used with getArticleContent. An array of Chromium flags to pass to the browser instance. By default, this will be an empty array. A full list of available flags can be found here. NB: if you are launching this in a Heroku app, you will need to pass the --no-sandbox and --disable-setuid-sandbox flags, as explained in this SO answer.
Defaults to []
Only used with getArticleContent. Whether or not Puppeteer should run in headless mode. Running in headless mode increases performance by approximately 30% (cred