A Happy and lightweight Python Package that Provides an API to search for articles on Google News and returns a JSON response.
[![Contributors][contributors-shield]][contributors-url] [![Forks][forks-shield]][forks-url] [![Stargazers][stars-shield]][stars-url] [![Issues][issues-shield]][issues-url] [![MIT License][license-shield]][license-url] [![Download][download-sheild]][download-url] [![LinkedIn][linkedin-shield]][linkedin-url] [![Docs][docs-shield]][docs-url]
Sponsored by SearchApi
GNews π°
A Happy and lightweight Python Package that Provides an API to search for articles on Google News and returns a usable JSON response! π
If you like β€οΈ GNews or find it useful π, support the project by buying me a coffee β.
π View Demo Β· π Report Bug Β· π Request Feature
Table of Contents π
About GNews
π© GNews is A Happy and lightweight Python Package that searches Google News RSS Feed and returns a usable JSON response \ π© As well as you can fetch full article (No need to write scrappers for articles fetching anymore)
Google News cover across 141+ countries with 41+ languages. On the bottom left side of the Google News page you may find a Language & region section where you can find all of the supported combinations.
Demo
[![GNews Demo][demo-gif]](https://github.com/ranahaani/GNews)
Getting Started
This section provides instructions for two different use cases:
- Installing the GNews package for immediate use.
- Setting up the GNews project for local development.
1. Installing the GNews package
To install the package and start using it in your own projects, follow these steps:
shell
pip install gnews
To also enable full article text extraction:
pip install gnews[fulltext]
To enable real article URL resolution (resolves Google News redirect URLs):
pip install gnews[playwright]
playwright install chromium
2. Setting Up GNews for Local Development
If you want to make modifications locally, follow these steps to set up the development environment.
Option 1: Setup with Docker
- Install docker and docker-compose.
- Configure the
.envfile by placing your MongoDB credentials. - Run the following command to build and start the Docker containers:
shell
docker-compose up --build
Option 2: Install Using Git Clone
- Clone this repository:
shell
git clone https://github.com/ranahaani/GNews.git
- Set up a virtual environment:
virtualenv venv
source venv/bin/activate # MacOS/Linux
.\venv\Scripts\activate # Windows
- Install the required dependencies:
pip install -r requirements.txt
Example usage
from gnews import GNews
google_news = GNews() pakistannews = googlenews.get_news('Pakistan') print(pakistan_news[0])
[{
'publisher': 'Aljazeera.com',
'description': 'Pakistan accuses India of stoking conflict in Indian Ocean '
'Aljazeera.com',
'published date': 'Tue, 16 Feb 2021 11:50:43 GMT',
'title': 'Pakistan accuses India of stoking conflict in Indian Ocean - '
'Aljazeera.com',
'url': 'https://www.aljazeera.com/news/2021/2/16/pakistan-accuses-india-of-nuclearizing-indian-ocean'
},
...]
π Interactive Tutorial
We have created a step-by-step [ jupyter Notebook tutorial ] that demonstrates:
- Basic usage and setup
- Filtering news (by topic, location, domain, date range, etc.)
- Exporting results (CSV, JSON)
- Real-world analysis: Sentiment Analysis on news headlines
- Advanced usage & best practices
- Interactive examples you can run line-by-line
This is the best way to learn GNews hands-on.
Get top news
GNews.gettopnews()
Get news by keyword
GNews.get_news(keyword)
Get news by major topic
GNews.getnewsby_topic(topic)- Available topics:
WORLD, NATION, BUSINESS, TECHNOLOGY, ENTERTAINMENT, SPORTS, SCIENCE, HEALTH, POLITICS, CELEBRITIES, TV, MUSIC, MOVIES, THEATER, SOCCER, CYCLING, MOTOR SPORTS, TENNIS, COMBAT SPORTS, BASKETBALL, BASEBALL, FOOTBALL, SPORTS BETTING, WATER SPORTS, HOCKEY, GOLF,
Get news by geo location
GNews.getnewsby_location(location)- location can be name of city/state/country
Get news by site
GNews.getnewsby_site(site)- site should be in the format of:
"cnn.com"
Results specification
All parameters are optional and can be passed during initialization. Hereβs a list of the available parameters:- language: The language in which to return results (default: 'en').
- country: The country code for the headlines (default: 'US').
- period: The time period for which you want news.
- start_date: Date after which results must have been published.
- end_date: Date before which results must have been published.
- max_results: The maximum number of results to return (default: 100).
- exclude_websites: A list of websites to exclude from results.
- max_retries: Retry attempts on HTTP 429 from Google News (default:
3). Set to0to disable retries. - retrybackoffbase: Base seconds for exponential backoff between retries (default:
1.0). Effective delay ismin(retrybackoffmax, retrybackoffbase 2 * attempt)plus uniform jitter in[0, retrybackoffbase). - retrybackoffmax: Cap (in seconds) for any single backoff delay (default:
60.0). - proxy: A dictionary specifying the proxy settings used to route requests. The dictionary should contain a single key-value pair where the key is the protocol (
httporhttps) and the value is the proxy address. Example:
# Example with only HTTP proxy
proxy = {
'http': 'http://yourproxyaddress',
}
Example with only HTTPS proxy
proxy = {
'https': 'http://yourproxyaddress',
}
Example Initialization
from gnews import GNews
Initialize GNews with various parameters, including proxy
google_news = GNews(
language='en',
country='US',
period='7d',
start_date=None,
end_date=None,
max_results=10,
exclude_websites=['yahoo.com', 'cnn.com'],
proxy={
'https': 'https://yourproxyaddress'
}
)
- Or change it to an existing object
google_news.period = '7d' # News from last 7 days
googlenews.maxresults = 10 # number of responses across a keyword
google_news.country = 'United States' # News from a specific country
google_news.language = 'english' # News in a specific language
googlenews.excludewebsites = ['yahoo.com', 'cnn.com'] # Exclude news from specific website i.e Yahoo.com and CNN.com
googlenews.startdate = (2020, 1, 1) # Search from 1st Jan 2020
googlenews.enddate = (2020, 3, 1) # Search until 1st March 2020
The format of the timeframe is a string comprised of a number, followed by a letter representing the time operator. For example 1y would signify 1 year. Full list of operators below:
- h = hours (eg: 12h)
- d = days (eg: 7d)
- m = months (eg: 6m)
- y = years (eg: 1y)
Setting the start and end dates can be done by passing in either a datetime or a tuple in the form (YYYY, MM, DD).
Supported Countries
print(googlenews.AVAILABLECOUNTRIES)
{'Australia': 'AU', 'Botswana': 'BW', 'Canada ': 'CA', 'Ethiopia': 'ET', 'Ghana': 'GH', 'India ': 'IN', 'Indonesia': 'ID', 'Ireland': 'IE', 'Israel ': 'IL', 'Kenya': 'KE', 'Latvia': 'LV', 'Malaysia': 'MY', 'Namibia': 'NA', 'New Zealand': 'NZ', 'Nigeria': 'NG', 'Pakistan': 'PK', 'Philippines': 'PH', 'Singapore': 'SG', 'South Africa': 'ZA', 'Tanzania': 'TZ', 'Uganda': 'UG', 'United Kingdom': 'GB', 'United States': 'US', 'Zimbabwe': 'ZW', 'Czech Republic': 'CZ', 'Germany': 'DE', 'Austria': 'AT', 'Switzerland': 'CH', 'Argentina': 'AR', 'Chile': 'CL', 'Colombia': 'CO', 'Cuba': 'CU', 'Mexico': 'MX', 'Peru': 'PE', 'Venezuela': 'VE', 'Belgium ': 'BE', 'France': 'FR', 'Morocco': 'MA', 'Senegal': 'SN', 'Italy': 'IT', 'Lithuania': 'LT', 'Hungary': 'HU', 'Netherlands': 'NL', 'Norway': 'NO', 'Poland': 'PL', 'Brazil': 'BR', 'Portugal': 'PT', 'Romania': 'RO', 'Slovakia': 'SK', 'Slovenia': 'SI', 'Sweden': 'SE', 'Vietnam': 'VN', 'Turkey': 'TR', 'Greece': 'GR', 'Bulgaria': 'BG', 'Russia': 'RU', 'Ukraine ': 'UA', 'Serbia': 'RS', 'United Arab Emirates': 'AE', 'Saudi Arabia': 'SA', 'Lebanon': 'LB', 'Egypt': 'EG', 'Bangladesh': 'BD', 'Thailand': 'TH', 'China': 'CN', 'Taiwan': 'TW', 'Hong Kong': 'HK', 'Japan': 'JP', 'Republic of Korea': 'KR'}
Supported Languages
print(googlenews.AVAILABLELANGUAGES)
{'english': 'en', 'indonesian': 'id', 'czech': 'cs', 'german': 'de', 'spanish': 'es-419', 'french': 'fr', 'italian': 'it', 'latvian': 'lv', 'lithuanian': 'lt', 'hungarian': 'hu', 'dutch': 'nl', 'norwegian': 'no', 'polish': 'pl', 'portuguese brasil': 'pt-419', 'portuguese portugal': 'pt-150', 'romanian': 'ro', 'slovak': 'sk', 'slovenian': 'sl', 'swedish': 'sv', 'vietnamese': 'vi', 'turkish': 'tr', 'greek': 'el', 'bulgarian': 'bg', 'russian': 'ru', 'serbian': 'sr', 'ukrainian': 'uk', 'hebrew': 'he', 'arabic': 'ar', 'marathi': 'mr', 'hindi': 'hi', 'bengali': 'bn', 'tamil': 'ta', 'telugu': 'te', 'malyalam': 'ml', 'thai': 'th', 'chinese simplified': 'zh-Hans', 'chinese traditional': 'zh-Hant', 'japanese': 'ja', 'korean': 'ko'}
Article Properties
- Get news returns a list of articles with the following keys:
| Field | Description | Example | |-------|-------------|---------| | title | Article title | "Pakistan PM calls for ceasefire" | | description | Short summary | "Pakistan's prime minister said..." | | published date | Published date (RFC 2822) | "Wed, 07 Jun 2026 07:01:30 GMT" | | url | Direct article URL | "https://bbc.com/news/..." | | publisher | Publisher name | "BBC News" |
SearchApi backend (additional fields):
| Field | Description | Example | |-------|-------------|---------| | iso_date | ISO 8601 publish date | "2026-06-07T07:01:30Z" | | thumbnail | Article image (base64) | "data:image/jpeg;base64,..." | | favicon | Publisher logo (base64) | "data:image/png;base64,..." | | rank | Position in search results | 1 |
Getting full article
First install the optional dependency:
pip install gnews[fulltext]
Then use getfullarticle():
from gnews import GNews
google_news = GNews() articles = googlenews.getnews(βPakistanβ) article = googlenews.getfull_article(articles[0][βurlβ])
print(article[βtextβ]) # full article text print(article[βurlβ]) # original URL
Note: Some sites block automated requests (paywalls, Cloudflare).getfullarticle()will raise aNetworkErrorin those cases.
Export Results
Save articles directly to JSON or CSV:
from gnews import GNews
g = GNews(max_results=10) articles = g.get_news("artificial intelligence")
Save to JSON
g.savetojson(articles, "news.json")
Save to CSV
g.savetocsv(articles, "news.csv")
Both methods return the output file path. No extra dependencies required.
CLI Usage
GNews includes a command-line interface out of the box:
# Search news
gnews search "artificial intelligence"
gnews search "Pakistan" --lang ur --country PK --max 5
Top headlines
gnews top
gnews top --max 10
By topic
gnews topic TECHNOLOGY
gnews topic BUSINESS --max 5
By site
gnews site bbc.com
gnews site cnn.com --max 3
By location
gnews location Pakistan
gnews location India --max 5
JSON output (pipe-friendly)
gnews search "OpenAI" --json
gnews top --json | python3 -m json.tool
Options available on all commands:
| Option | Default | Description | |--------|---------|-------------| | --lang | en | Language code | | --country | US | Country code | | --max | 10 | Max results | | --json | off | Output as JSON |
SearchApi Integration
GNews supports SearchApi as an optional backend. When a searchapi_key is provided, GNews uses SearchApi instead of the default Google News RSS feed.
Benefits over RSS:
- Resolved article URLs (fixes broken redirect links, see #62)
- Pagination beyond the ~100-result RSS cap
- Richer article data:
thumbnail,favicon,iso_date,rank,snippet - No IP blocks or rate limits from Google
Setup
pip install gnews
Get a free API key at searchapi.io.
Usage
from gnews import GNews
Pass your SearchApi key to enable the SearchApi backend
googlenews = GNews(searchapikey="YOURSEARCHAPIKEY")
All existing methods work as before
articles = googlenews.getnews("artificial intelligence")
print(articles[0])
{
'title': 'OpenAI announces new model',
'description': 'Article snippet from SearchApi...',
'published date': '2 hours ago',
'iso_date': '2026-06-11T10:00:00Z',
'url': 'https://techcrunch.com/2026/06/11/openai-new-model',
'publisher': 'TechCrunch',
'thumbnail': 'data:image/jpeg;base64,...',
'favicon': 'data:image/png;base64,...',
'rank': 1
}
Pagination
googlenews = GNews(searchapikey="YOURKEY", maxresults=50)
Get page 2 results (breaks past the ~100 RSS cap)
articles = googlenews.getnews("Python", page=2)
Additional article fields (SearchApi backend only)
| Field | Description | |---|---| | iso_date | Absolute ISO 8601 publish date | | thumbnail | Article image (base64) | | favicon | Publisher logo (base64) | | rank | Position in search results |
The RSS backend (default, no API key required) continues to work exactly as before. The SearchApi backend is fully opt-in.
Async Support
All search methods have async equivalents β no new dependencies required:
import asyncio
from gnews import GNews
g = GNews(max_results=10)
Single async query
articles = asyncio.run(g.getnewsasync("AI"))
Fetch multiple topics concurrently
async def main():
ai, python, pakistan = await asyncio.gather(
g.getnewsasync("AI"),
g.getnewsasync("Python"),
g.getnewsasync("Pakistan"),
)
return ai, python, pakistan
asyncio.run(main())
| Async method | Sync equivalent | |---|---| | getnewsasync(key, page=1) | get_news() | | gettopnewsasync() | gettop_news() | | getnewsbytopicasync(topic) | getnewsby_topic() | | getnewsbylocationasync(location) | getnewsby_location() | | getnewsbysiteasync(site) | getnewsby_site() |
URL Resolution
By default, Google News RSS returns redirect URLs (news.google.com/rss/articles/...) instead of real article URLs. Google requires JavaScript execution to resolve them β plain HTTP requests cannot follow these redirects.
Install the optional Playwright extra to get real article URLs automatically:
pip install gnews[playwright]
playwright install chromium # one-time setup
Once installed, URL resolution is automatic β no code changes needed:
from gnews import GNews
g = GNews(max_results=5) articles = g.get_news("AI")
With gnews[playwright] installed:
print(articles[0]['url']) # https://www.politico.com/news/...
Without gnews[playwright]:
print(articles[0]['url']) # https://news.google.com/rss/articles/...
If resolution fails for a specific article (paywall, timeout, consent gate), GNews falls back to the Google URL silently β it never crashes.
Note: For production use without Playwright, the SearchApi backend always returns real article URLs with zero setup beyond an API key.
Todo
- Save to MongoDB
- Save to SQLite
Save to JSONβSave to .CSV fileβMore than 100 articlesβAsync supportβReal article URL resolutionβ- FastAPI wrapper
Roadmap
See the open issues for a list of proposed features (and known issues).
Contributing
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
License
Distributed under the MIT License. See LICENSE for more information.
Contact
Muhammad Abdullah - @ranahaani - ranahaani@gmail.com
Project Link: https://github.com/ranahaani/GNews
[contributors-shield]: https://img.shields.io/github/contributors/ranahaani/GNews.svg?style=for-the-badge
[contributors-url]: https://github.com/ranahaani/GNews/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/ranahaani/GNews.svg?style=for-the-badge
[forks-url]: https://github.com/ranahaani/GNews/network/members
[stars-shield]: https://img.shields.io/github/stars/ranahaani/GNews.svg?style=for-the-badge
[stars-url]: https://github.com/ranahaani/GNews/stargazers
[issues-shield]: https://img.shields.io/github/issues/ranahaani/GNews.svg?style=for-the-badge
[issues-url]: https://github.com/ranahaani/GNews/issues
[license-shield]: https://img.shields.io/github/license/ranahaani/GNews.svg?style=for-the-badge
[license-url]: https://github.com/ranahaani/GNews/blob/master/LICENSE.txt
[download-sheild]: https://img.shields.io/pypi/dm/GNews.svg?style=for-the-badge
[download-url]: https://pypistats.org/packages/gnews
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555
[linkedin-url]: https://linkedin.com/in/ranahaani
[docs-shield]: https://img.shields.io/readthedocs/gnews?style=for-the-badge
[docs-url]: https://gnews.readthedocs.io/en/latest/
[demo-gif]: https://github.com/ranahaani/GNews/raw/master/imgs/gnews.gif