rss-parser
Typed, pydantic-powered RSS/Atom parsing for Python.
rss-parser turns RSS/Atom XML into typed pydantic models —
autocomplete, validation, and clear errors instead of digging through nested dicts.
At a glance
| Ecosystem | Python 3.10+ — installed with pip install rss-parser, imported as rss_parser. This is not the npm package of the same name; there is no JavaScript/Node.js distribution. |
| Feed formats | RSS 2.0, RSS 0.91/0.92, Atom 1.0, RSS 1.0 (RDF), plus typed Apple Podcasts (itunes:*) extensions |
| Runtime dependencies | pydantic v2 (>=2.7), xmltodict, typing-extensions |
| Repository | github.com/dhvcc/rss-parser |
| Documentation | dhvcc.github.io/rss-parser |
| Package | pypi.org/project/rss-parser |
| License | GPL-3.0 |
| Issues | github.com/dhvcc/rss-parser/issues |
| Security | Report vulnerabilities privately — see SECURITY.md. Do not open a public issue. |
Installation
pip install rss-parser
For AI coding agents
skills/rss-parser/SKILL.md is an
Agent Skill: the API model, recipes and the pitfalls that
trip agents up, in one file. Install it into Claude Code, Cursor, Copilot, Codex and friends with:
npx skills add dhvcc/rss-parser
The library also ships context7.json,
so Context7 serves these docs with Python-specific rules.
Parsing from a URL
rss-parser does not fetch anything — it parses text you already have, so there is no
parseURL/parseString (that is the npm package). Bring your own HTTP client:
import requests
from rss_parser import parse
feed = parse(requests.get(url, timeout=10).text)
parse() accepts str or bytes — pass response.content and the feed's own encoding
declaration is honored, which matters for feeds that are not UTF-8.
Polling, conditional GET, deduplication by guid/id and normalizing across RSS/Atom/RDF are
covered in Fetching feeds from a URL.
Quickstart
from rss_parser import parse
from requests import get # noqa
rss_url = "https://rss.art19.com/apology-line"
response = get(rss_url)
feed = parse(response.content) # detects RSS 2.0 / 0.9x, Atom 1.0 or RSS 1.0 (RDF)
print("Language", feed.channel.language)
print("RSS", feed.version)
for item in feed.channel.items:
print(item.title)
print(str(item.description)[:50])
# Language en
# RSS 2.0
# Wondery Presents - Flipping The Bird: Elon vs Twitter
# <p>When Elon Musk posted a video of himself arrivi
# Introducing: The Apology Line
# <p>If you could call a number and say you’re sorry
parse() picks the right parser from the XML root element and raises UnknownFeedTypeError
if the document is not a feed. If you already know the feed type, use the explicit parsers:
RSSParser, AtomParser, RDFParser, PodcastParser.
Podcasts
itunes:* tags are supported out of the box, fully typed:
from rss_parser import PodcastParser
podcast = PodcastParser.parse(feed_xml)
channel = podcast.channel.content
channel.itunes_author # 'Wondery'
channel.itunes_owner.content.email # 'iwonder@wondery.com'
channel.itunes_image.attributes["href"] # artwork url
episode = channel.items[0].content
episode.itunes_duration # '00:05:01'
episode.itunes_episode_type # 'trailer'
Custom fields: one subclass away
The models are generic, so extending the schema doesn't require re-declaring the whole tree:
from typing import Optional
from pydantic import Field
from rss_parser import RSSParser
from rss_parser.models.rss import RSS, Channel, Item
from rss_parser.models.types import Tag
class MyItem(Item):
dc_creator: Optional[Tag[str]] = Field(alias="dc:creator", default=None)
rss = RSSParser.parse(data, schema=RSS[Channel[MyItem]])
rss.channel.items[0].content.dc_creator
And even without a custom schema, unknown tags are never dropped — they're kept in model_extra:
rss = RSSParser.parse(podcast_xml)
rss.channel.content.model_extra["itunes:author"] # 'Wondery'
See Customizing the schema for mixins, repeatable tags, and the field types cheat sheet.
Migrating from 3.x
4.0 removes the legacy pydantic v1 models, fixes several RSS 2.0 spec violations, and makes the models generic and lossless. See the migration guide for the full list.
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Install dependencies with uv sync (install uv).
Using pre-commit is highly recommended. To install hooks, run:
uv run pre-commit install -t=pre-commit -t=pre-push
See Contributing for tests, snapshots, and docs.
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rss_parser-4.2.1.tar.gz.
File metadata
- Download URL: rss_parser-4.2.1.tar.gz
- Upload date:
- Size: 330.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.33 {"installer":{"name":"uv","version":"0.11.33","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
043f35eec7b4fe88d6fcfa8d00b0936104776eca1673cff3049b35d66b4ed1a4
|
|
| MD5 |
e9e45338889df7a7ad31af005b6db815
|
|
| BLAKE2b-256 |
967988c3353a66236b2d10a51acb6559ffef6f45bb7428559eaf8532e6659ed5
|
File details
Details for the file rss_parser-4.2.1-py3-none-any.whl.
File metadata
- Download URL: rss_parser-4.2.1-py3-none-any.whl
- Upload date:
- Size: 38.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.33 {"installer":{"name":"uv","version":"0.11.33","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
235ae7cd94f787b30a4784020dddb9d556f93211ff42cb344d6513b909120ee2
|
|
| MD5 |
ff4378abdb923ba7f36c5a54cdb6a008
|
|
| BLAKE2b-256 |
92847fb07430a97d106be11e76a9a34b063cdf088379bcace165dff0b84e5c05
|