Google News Decoder
Google News Decoder is a Python package that can decode Google News links or Google News URLs to their original URLs. It is a simple tool that saves you time and effort. If you find it useful, please support the package by hitting the star on GitHub. Your support helps keep the project going!
Use googlenewsdecoder to decode a Google News URL, extract the original article URL from news.google.com/read/, /articles/, or Google News RSS /rss/articles/ feeds, and resolve the Google News redirect to the publisher source. Works with pip install googlenewsdecoder or uv add googlenewsdecoder on Python 3.11+.
Looking for a sponsor
Demo
How it works
Google News wraps every story in an encoded link. After 2024 that id is opaque — it is not a base64 publisher URL.
This package fetches the per-article signature from Google News, then resolves the original URL with one batchexecute POST. Pass a list and those signatures share that single POST (no for-loop of POSTs).
Accepted input:
https://news.google.com/read/...https://news.google.com/articles/...https://news.google.com/rss/articles/...
Each result is {"success": True, "decoded_url": "..."} or {"success": False, "message": "..."}.
Installation
uv add googlenewsdecoder
pip install googlenewsdecoder
pip install googlenewsdecoder --upgrade
This repo uses uv:
uv sync --group dev
Parameters
| Parameter | Default | What it is |
|---|---|---|
source_url |
required | One Google News URL, or a list of them. |
interval |
None |
Seconds to wait after each article-page fetch. Use on large batches if you hit HTTP 429. |
proxy |
None |
Optional HTTP/HTTPS/SOCKS5 proxy if this IP is rate-limited. |
timeout |
10.0 |
Seconds per HTTP call. None waits indefinitely. |
concurrency |
8 |
Async list only. Max parallel article-page fetches. |
proxy stays None unless you need one. Examples:
http://user:pass@host:port
https://host:port
socks5://user:pass@host:port
Usage
Sync — gnewsdecoder
from googlenewsdecoder import gnewsdecoder
def main():
interval_time = 1 # optional; None means no wait
timeout = 15.0
# Optional. Examples:
# proxy = "http://user:pass@host:port"
# proxy = "https://host:port"
# proxy = "socks5://user:pass@host:port"
proxy = None
source_url = "https://news.google.com/read/CBMi2AFBVV95cUxPd1ZCc1loODVVNHpnbFFTVHFkTG94eWh1NWhTeE9yT1RyNTRXMVV2S1VIUFM3ZlVkVjl6UHh3RkJ0bXdaTVRlcHBjMWFWTkhvZWVuM3pBMEtEdlllRDBveGdIUm9GUnJ4ajd1YWR5cWs3VFA5V2dsZnY1RDZhVDdORHRSSE9EalF2TndWdlh4bkJOWU5UMTdIV2RCc285Q2p3MFA4WnpodUNqN1RNREMwa3d5T2ZHS0JlX0MySGZLc01kWDNtUEkzemtkbWhTZXdQTmdfU1JJaXY?hl=en-US&gl=US&ceid=US%3Aen"
try:
result = gnewsdecoder(
source_url,
interval=interval_time,
proxy=proxy,
timeout=timeout,
)
if result["success"]:
print("Decoded URL:", result["decoded_url"])
else:
print("Error:", result["message"])
except Exception as e:
print(f"Error occurred: {e}")
if __name__ == "__main__":
main()
Async — gnews_decoder_async
import asyncio
from googlenewsdecoder import gnews_decoder_async
def main():
interval_time = 1 # optional; None means no wait
timeout = 15.0
# Optional. Examples:
# proxy = "http://user:pass@host:port"
# proxy = "https://host:port"
# proxy = "socks5://user:pass@host:port"
proxy = None
source_url = "https://news.google.com/read/CBMi2AFBVV95cUxPd1ZCc1loODVVNHpnbFFTVHFkTG94eWh1NWhTeE9yT1RyNTRXMVV2S1VIUFM3ZlVkVjl6UHh3RkJ0bXdaTVRlcHBjMWFWTkhvZWVuM3pBMEtEdlllRDBveGdIUm9GUnJ4ajd1YWR5cWs3VFA5V2dsZnY1RDZhVDdORHRSSE9EalF2TndWdlh4bkJOWU5UMTdIV2RCc285Q2p3MFA4WnpodUNqN1RNREMwa3d5T2ZHS0JlX0MySGZLc01kWDNtUEkzemtkbWhTZXdQTmdfU1JJaXY?hl=en-US&gl=US&ceid=US%3Aen"
try:
result = asyncio.run(
gnews_decoder_async(
source_url,
interval=interval_time,
proxy=proxy,
timeout=timeout,
)
)
if result["success"]:
print("Decoded URL:", result["decoded_url"])
else:
print("Error:", result["message"])
except Exception as e:
print(f"Error occurred: {e}")
if __name__ == "__main__":
main()
Async batch
Pass a list. Article pages can run in parallel; decode is still one POST.
import asyncio
from googlenewsdecoder import gnews_decoder_async
def main():
interval_time = 1 # optional; None means no wait
timeout = 15.0
# Optional. Examples:
# proxy = "http://user:pass@host:port"
# proxy = "https://host:port"
# proxy = "socks5://user:pass@host:port"
proxy = None
source_urls = [
"https://news.google.com/read/CBMi2AFBVV95cUxPd1ZCc1loODVVNHpnbFFTVHFkTG94eWh1NWhTeE9yT1RyNTRXMVV2S1VIUFM3ZlVkVjl6UHh3RkJ0bXdaTVRlcHBjMWFWTkhvZWVuM3pBMEtEdlllRDBveGdIUm9GUnJ4ajd1YWR5cWs3VFA5V2dsZnY1RDZhVDdORHRSSE9EalF2TndWdlh4bkJOWU5UMTdIV2RCc285Q2p3MFA4WnpodUNqN1RNREMwa3d5T2ZHS0JlX0MySGZLc01kWDNtUEkzemtkbWhTZXdQTmdfU1JJaXY?hl=en-US&gl=US&ceid=US%3Aen",
"https://news.google.com/rss/articles/CBMiiAFBVV95cUxQOXZLdC1hSzFqQVVLWGJVZzlPaDYyNjdWTURScV9BbVp0SWhFNzZpSWZxSzdhc0tKbVlHMU13NmZVOFdidFFkajZPTm9SRnlZMWFRZ01CVHh0dXU0TjNVMUxZNk9Ibk5DV3hrYlRiZ20zYkIzSFhMQVVpcTFPc00xQjhhcGV1aXM?hl=en-US&gl=US&ceid=US%3Aen",
]
try:
results = asyncio.run(
gnews_decoder_async(
source_urls,
interval=interval_time,
proxy=proxy,
timeout=timeout,
)
)
for result in results:
if result["success"]:
print("Decoded URL:", result["decoded_url"])
else:
print("Error:", result["message"])
except Exception as e:
print(f"Error occurred: {e}")
if __name__ == "__main__":
main()
gnewsdecoder(source_urls) also accepts a list (sync fetch, one POST). For many URLs, async batch is the better call.
Credits
- Original script by huksley
Star History
Metadata
Release files for googlenewsdecoder 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| googlenewsdecoder-0.2.1.tar.gz | 8.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| googlenewsdecoder-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.8 kB
Release files / googlenewsdecoder-0.2.1.tar.gz
| Download URL | googlenewsdecoder-0.2.1.tar.gz |
|---|---|
| Size | 8.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
12aa4fa6b1d48012225dc20906c49ef386c850bdb4236a63968cb871c2f250e0
|
|
BLAKE2b-256 checksum How to use checksums |
04fce98ba1b5aca91043cd42824e22920d270fd6fa02f26b74d8096dadadeb62
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / googlenewsdecoder-0.2.1-py3-none-any.whl
| Download URL | googlenewsdecoder-0.2.1-py3-none-any.whl |
|---|---|
| Size | 11.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a7adecb3edc43cb7106a67c89171b99a19e083b62750fb364528b4057e29497a
|
|
BLAKE2b-256 checksum How to use checksums |
afbc530ea99ba7416d758e0594124e1733fd3afbf3ef8748125244be64e00cde
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|