How to Fetch Real-Time News in Python (3 Practical Examples)

How to Fetch Real-Time News in Python (3 Practical Examples)

Source: Dev.to

Prerequisites ## Example 1: Fetch Trending News ## Example 2: Filter News by Category and Country ## Available Categories ## Supported Countries ## Example 3: Search News by Keyword ## Bonus: Simple News Monitoring Script ## Handling Pagination ## Error Handling Best Practices ## What Can You Build? ## Wrapping Up Whether you're building a news aggregator, a trading bot that reacts to headlines, or just want to add a news feed to your app - fetching real-time news in Python is surprisingly simple. In this tutorial, I'll show you 3 practical examples using a news API, from basic fetching to building a simple news monitoring script. Let's start simple - get the top trending stories right now: Need sports news from the UK? Or tech news from the US? Easy: 35+ countries including: us, gb, ca, au, de, fr, jp, in, br, and more. Search for specific topics across all articles: Here's a practical script that monitors news for specific keywords and prints new articles: For fetching more than 25 articles, use the next_cursor returned in responses: Always handle API errors gracefully: Fetching news in Python is straightforward once you have a reliable API. The examples above should get you started quickly. What are you building with news data? Drop a comment below - I'd love to hear about your projects! Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse COMMAND_BLOCK: import requests API_KEY = "your_api_key_here" BASE_URL = "https://api.newsmesh.co/v1" def get_trending_news(limit=10): """Fetch currently trending news articles.""" response = requests.get( f"{BASE_URL}/trending", params={"apiKey": API_KEY, "limit": limit} ) response.raise_for_status() return response.json()["data"] # Usage for article in get_trending_news(): print(f"šŸ“° {article['title']}") print(f" Source: {article['source']} | Category: {article['category']}") print(f" Link: {article['link']}\n") Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: import requests API_KEY = "your_api_key_here" BASE_URL = "https://api.newsmesh.co/v1" def get_trending_news(limit=10): """Fetch currently trending news articles.""" response = requests.get( f"{BASE_URL}/trending", params={"apiKey": API_KEY, "limit": limit} ) response.raise_for_status() return response.json()["data"] # Usage for article in get_trending_news(): print(f"šŸ“° {article['title']}") print(f" Source: {article['source']} | Category: {article['category']}") print(f" Link: {article['link']}\n") COMMAND_BLOCK: import requests API_KEY = "your_api_key_here" BASE_URL = "https://api.newsmesh.co/v1" def get_trending_news(limit=10): """Fetch currently trending news articles.""" response = requests.get( f"{BASE_URL}/trending", params={"apiKey": API_KEY, "limit": limit} ) response.raise_for_status() return response.json()["data"] # Usage for article in get_trending_news(): print(f"šŸ“° {article['title']}") print(f" Source: {article['source']} | Category: {article['category']}") print(f" Link: {article['link']}\n") CODE_BLOCK: šŸ“° Fed Signals Rate Cut in Early 2025 Source: Reuters | Category: business Link: https://reuters.com/... šŸ“° OpenAI Announces GPT-5 Preview Source: TechCrunch | Category: technology Link: https://techcrunch.com/... Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: šŸ“° Fed Signals Rate Cut in Early 2025 Source: Reuters | Category: business Link: https://reuters.com/... šŸ“° OpenAI Announces GPT-5 Preview Source: TechCrunch | Category: technology Link: https://techcrunch.com/... CODE_BLOCK: šŸ“° Fed Signals Rate Cut in Early 2025 Source: Reuters | Category: business Link: https://reuters.com/... šŸ“° OpenAI Announces GPT-5 Preview Source: TechCrunch | Category: technology Link: https://techcrunch.com/... COMMAND_BLOCK: def get_latest_news(category=None, country=None, limit=10): """ Fetch latest news with optional filters. Args: category: politics, technology, business, health, entertainment, sports, science, lifestyle, environment, world country: ISO code like 'us', 'gb', 'de', 'fr', etc. limit: max 25 articles per request """ params = {"apiKey": API_KEY, "limit": limit} if category: params["category"] = category if country: params["country"] = country response = requests.get(f"{BASE_URL}/latest", params=params) response.raise_for_status() return response.json()["data"] # Get technology news from the US tech_news = get_latest_news(category="technology", country="us") # Get sports news from the UK uk_sports = get_latest_news(category="sports", country="gb") # Get all business news business = get_latest_news(category="business", limit=25) Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: def get_latest_news(category=None, country=None, limit=10): """ Fetch latest news with optional filters. Args: category: politics, technology, business, health, entertainment, sports, science, lifestyle, environment, world country: ISO code like 'us', 'gb', 'de', 'fr', etc. limit: max 25 articles per request """ params = {"apiKey": API_KEY, "limit": limit} if category: params["category"] = category if country: params["country"] = country response = requests.get(f"{BASE_URL}/latest", params=params) response.raise_for_status() return response.json()["data"] # Get technology news from the US tech_news = get_latest_news(category="technology", country="us") # Get sports news from the UK uk_sports = get_latest_news(category="sports", country="gb") # Get all business news business = get_latest_news(category="business", limit=25) COMMAND_BLOCK: def get_latest_news(category=None, country=None, limit=10): """ Fetch latest news with optional filters. Args: category: politics, technology, business, health, entertainment, sports, science, lifestyle, environment, world country: ISO code like 'us', 'gb', 'de', 'fr', etc. limit: max 25 articles per request """ params = {"apiKey": API_KEY, "limit": limit} if category: params["category"] = category if country: params["country"] = country response = requests.get(f"{BASE_URL}/latest", params=params) response.raise_for_status() return response.json()["data"] # Get technology news from the US tech_news = get_latest_news(category="technology", country="us") # Get sports news from the UK uk_sports = get_latest_news(category="sports", country="gb") # Get all business news business = get_latest_news(category="business", limit=25) COMMAND_BLOCK: def search_news(query, from_date=None, to_date=None, sort_by="date_descending"): """ Search news articles by keyword. Args: query: Search term (e.g., "bitcoin", "climate change") from_date: Start date as YYYY-MM-DD to_date: End date as YYYY-MM-DD sort_by: 'date_descending', 'date_ascending', or 'relevant' """ params = { "apiKey": API_KEY, "q": query, "sortBy": sort_by, "limit": 25 } if from_date: params["from"] = from_date if to_date: params["to"] = to_date response = requests.get(f"{BASE_URL}/search", params=params) response.raise_for_status() return response.json()["data"] # Search for Bitcoin news from the last week bitcoin_news = search_news( query="bitcoin", from_date="2024-12-23", sort_by="relevant" ) for article in bitcoin_news[:5]: print(f"• {article['title']}") print(f" {article['published_date'][:10]} - {article['source']}\n") Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: def search_news(query, from_date=None, to_date=None, sort_by="date_descending"): """ Search news articles by keyword. Args: query: Search term (e.g., "bitcoin", "climate change") from_date: Start date as YYYY-MM-DD to_date: End date as YYYY-MM-DD sort_by: 'date_descending', 'date_ascending', or 'relevant' """ params = { "apiKey": API_KEY, "q": query, "sortBy": sort_by, "limit": 25 } if from_date: params["from"] = from_date if to_date: params["to"] = to_date response = requests.get(f"{BASE_URL}/search", params=params) response.raise_for_status() return response.json()["data"] # Search for Bitcoin news from the last week bitcoin_news = search_news( query="bitcoin", from_date="2024-12-23", sort_by="relevant" ) for article in bitcoin_news[:5]: print(f"• {article['title']}") print(f" {article['published_date'][:10]} - {article['source']}\n") COMMAND_BLOCK: def search_news(query, from_date=None, to_date=None, sort_by="date_descending"): """ Search news articles by keyword. Args: query: Search term (e.g., "bitcoin", "climate change") from_date: Start date as YYYY-MM-DD to_date: End date as YYYY-MM-DD sort_by: 'date_descending', 'date_ascending', or 'relevant' """ params = { "apiKey": API_KEY, "q": query, "sortBy": sort_by, "limit": 25 } if from_date: params["from"] = from_date if to_date: params["to"] = to_date response = requests.get(f"{BASE_URL}/search", params=params) response.raise_for_status() return response.json()["data"] # Search for Bitcoin news from the last week bitcoin_news = search_news( query="bitcoin", from_date="2024-12-23", sort_by="relevant" ) for article in bitcoin_news[:5]: print(f"• {article['title']}") print(f" {article['published_date'][:10]} - {article['source']}\n") COMMAND_BLOCK: import requests import time from datetime import datetime API_KEY = "your_api_key_here" KEYWORDS = ["AI", "OpenAI", "GPT"] # Topics to monitor CHECK_INTERVAL = 300 # Check every 5 minutes seen_articles = set() def check_for_news(): """Check for new articles matching our keywords.""" for keyword in KEYWORDS: response = requests.get( "https://api.newsmesh.co/v1/search", params={"apiKey": API_KEY, "q": keyword, "limit": 5} ) if response.status_code != 200: continue for article in response.json().get("data", []): article_id = article["article_id"] if article_id not in seen_articles: seen_articles.add(article_id) print(f"\nšŸ”” NEW: {article['title']}") print(f" Keyword: {keyword} | Source: {article['source']}") print(f" Link: {article['link']}") if __name__ == "__main__": print(f"Monitoring news for: {', '.join(KEYWORDS)}") print("Press Ctrl+C to stop\n") while True: check_for_news() time.sleep(CHECK_INTERVAL) Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: import requests import time from datetime import datetime API_KEY = "your_api_key_here" KEYWORDS = ["AI", "OpenAI", "GPT"] # Topics to monitor CHECK_INTERVAL = 300 # Check every 5 minutes seen_articles = set() def check_for_news(): """Check for new articles matching our keywords.""" for keyword in KEYWORDS: response = requests.get( "https://api.newsmesh.co/v1/search", params={"apiKey": API_KEY, "q": keyword, "limit": 5} ) if response.status_code != 200: continue for article in response.json().get("data", []): article_id = article["article_id"] if article_id not in seen_articles: seen_articles.add(article_id) print(f"\nšŸ”” NEW: {article['title']}") print(f" Keyword: {keyword} | Source: {article['source']}") print(f" Link: {article['link']}") if __name__ == "__main__": print(f"Monitoring news for: {', '.join(KEYWORDS)}") print("Press Ctrl+C to stop\n") while True: check_for_news() time.sleep(CHECK_INTERVAL) COMMAND_BLOCK: import requests import time from datetime import datetime API_KEY = "your_api_key_here" KEYWORDS = ["AI", "OpenAI", "GPT"] # Topics to monitor CHECK_INTERVAL = 300 # Check every 5 minutes seen_articles = set() def check_for_news(): """Check for new articles matching our keywords.""" for keyword in KEYWORDS: response = requests.get( "https://api.newsmesh.co/v1/search", params={"apiKey": API_KEY, "q": keyword, "limit": 5} ) if response.status_code != 200: continue for article in response.json().get("data", []): article_id = article["article_id"] if article_id not in seen_articles: seen_articles.add(article_id) print(f"\nšŸ”” NEW: {article['title']}") print(f" Keyword: {keyword} | Source: {article['source']}") print(f" Link: {article['link']}") if __name__ == "__main__": print(f"Monitoring news for: {', '.join(KEYWORDS)}") print("Press Ctrl+C to stop\n") while True: check_for_news() time.sleep(CHECK_INTERVAL) COMMAND_BLOCK: def get_all_articles(category, max_articles=100): """Fetch multiple pages of articles.""" all_articles = [] cursor = None while len(all_articles) < max_articles: params = {"apiKey": API_KEY, "category": category, "limit": 25} if cursor: params["cursor"] = cursor response = requests.get(f"{BASE_URL}/latest", params=params) data = response.json() all_articles.extend(data["data"]) cursor = data.get("next_cursor") if not cursor: # No more pages break return all_articles[:max_articles] Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: def get_all_articles(category, max_articles=100): """Fetch multiple pages of articles.""" all_articles = [] cursor = None while len(all_articles) < max_articles: params = {"apiKey": API_KEY, "category": category, "limit": 25} if cursor: params["cursor"] = cursor response = requests.get(f"{BASE_URL}/latest", params=params) data = response.json() all_articles.extend(data["data"]) cursor = data.get("next_cursor") if not cursor: # No more pages break return all_articles[:max_articles] COMMAND_BLOCK: def get_all_articles(category, max_articles=100): """Fetch multiple pages of articles.""" all_articles = [] cursor = None while len(all_articles) < max_articles: params = {"apiKey": API_KEY, "category": category, "limit": 25} if cursor: params["cursor"] = cursor response = requests.get(f"{BASE_URL}/latest", params=params) data = response.json() all_articles.extend(data["data"]) cursor = data.get("next_cursor") if not cursor: # No more pages break return all_articles[:max_articles] CODE_BLOCK: def safe_api_call(endpoint, params): """Make API call with proper error handling.""" try: response = requests.get(endpoint, params=params, timeout=10) response.raise_for_status() return response.json() except requests.exceptions.Timeout: print("Request timed out. Try again.") return None except requests.exceptions.HTTPError as e: error_data = e.response.json() print(f"API Error: {error_data.get('message', 'Unknown error')}") return None except requests.exceptions.RequestException as e: print(f"Request failed: {e}") return None Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: def safe_api_call(endpoint, params): """Make API call with proper error handling.""" try: response = requests.get(endpoint, params=params, timeout=10) response.raise_for_status() return response.json() except requests.exceptions.Timeout: print("Request timed out. Try again.") return None except requests.exceptions.HTTPError as e: error_data = e.response.json() print(f"API Error: {error_data.get('message', 'Unknown error')}") return None except requests.exceptions.RequestException as e: print(f"Request failed: {e}") return None CODE_BLOCK: def safe_api_call(endpoint, params): """Make API call with proper error handling.""" try: response = requests.get(endpoint, params=params, timeout=10) response.raise_for_status() return response.json() except requests.exceptions.Timeout: print("Request timed out. Try again.") return None except requests.exceptions.HTTPError as e: error_data = e.response.json() print(f"API Error: {error_data.get('message', 'Unknown error')}") return None except requests.exceptions.RequestException as e: print(f"Request failed: {e}") return None - Python 3.7+ - requests library (pip install requests) - A free API key from NewsMesh (free tier available) - politics - Political news - technology - Tech, startups, gadgets - business - Markets, finance, economy - health - Medical, wellness - entertainment - Celebrity, movies, music - sports - All sports coverage - science - Scientific discoveries - lifestyle - Culture, trends - environment - Climate, sustainability - world - International news - News digest bot - Daily email/Slack summary of topics you care about - Trading signals - React to financial news in real-time - Content aggregator - Build your own Google News - Research tool - Track coverage of specific companies or topics - News widget - Add a live news feed to your website - NewsMesh API Docs - Get a free API key