Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
437: Building a Simple RSS Feed Reader
I've always loved RSS. Even in the age of algorithmic feeds, there's something satisfying about a chronological list of updates from sources you actually chose. Today, I want to build a simple reader. I've got a few blogs I follow—let's use the official Python blog for this—and I want to pull the latest headlines into my terminal.
Just grabbing the raw data
My first instinct is usually to just grab the URL and see what's inside. I'll use requests since we've already covered it in previous lessons. I'm expecting some structured data, but I want to see the "skeleton" first.
import requests
url = "https://blog.python.org/feeds/posts/default"
response = requests.get(url)
print(response.text[:500]) # Just the first 500 characters
When I run this, I get a wall of XML. It looks like a bunch of <entry> tags, <title> tags, and some weird namespaces like xmlns:atom. It's readable to a human, but if I try to parse this using basic string splitting or even regular expressions, I'm going to have a bad time. XML is notoriously finicky.
The struggle with manual parsing
I could use Python's built-in xml.etree.ElementTree. I'll try to grab the first title just to see if it's straightforward.
import xml.etree.ElementTree as ET
import requests
url = "https://blog.python.org/feeds/posts/default"
response = requests.get(url)
root = ET.fromstring(response.content)
# I'll try to find all 'title' tags
for title in root.findall('.//title'):
print(title.text)
Wait, it didn't print anything. Why? I can see the <title> tags in the raw text. Ah, right—namespaces. That xmlns attribute in the root tag means the elements aren't just called "title"; they are called "{http://www.w3.org/2005/Atom}title". To make this work, I'd have to define a namespace dictionary and pass it into every single find call. It's tedious, and if I want to support both RSS 2.0 and Atom feeds (the two most common standards), I'd be writing a mountain of conditional logic just to handle the different tag names.
Finding a better way
This is exactly why the feedparser library exists. It's the industry standard for a reason: it doesn't care if the feed is RSS 1.0, 2.0, or Atom. It just flattens everything into a clean Python dictionary. Let's swap out my manual XML logic for this.
# First, you'd need: pip install feedparser
import feedparser
url = "https://blog.python.org/feeds/posts/default"
feed = feedparser.parse(url)
print(feed.feed.title)
That worked instantly. No namespaces, no ET.fromstring, no headache. The feed object now contains a feed attribute (for the overall site info) and an entries list (for the actual posts). This is much more intuitive.
Polishing the output
Right now, if I just print the entries, I'll get a massive list of dictionaries. I only care about the title and the link. Let's loop through the first five entries and format them so they actually look like a news feed.
import feedparser
url = "https://blog.python.org/feeds/posts/default"
feed = feedparser.parse(url)
print(f"--- {feed.feed.title} ---")
for entry in feed.entries[:5]:
print(f"\n{entry.title}")
print(f"Read more at: {entry.link}")
There we go. It's clean, it's robust, and it handles the underlying XML mess behind the scenes. The beauty here is that if I change the URL to a different site's RSS feed, the code stays exactly the same. feedparser handles the translation for us.
📋 Practical Task
Build a Multi-Source News Aggregator
Now it's your turn. Instead of tracking just one blog, create a script that tracks a list of multiple RSS feeds.
- Create a list called
sourcescontaining at least three different RSS feed URLs (you can use the Python blog, a news site like BBC or CNN, or any other public feed you find). - Write a loop that iterates through these sources, parses each one using
feedparser, and prints the site name followed by the titles of the top 3 most recent articles from that site. - Ensure that if a feed fails to load or is empty, your program doesn't crash—use a
try/exceptblock or a simpleifcheck to handle emptyentrieslists.
There are no comments for now.