RSS & Atom Structured Feed Extractor
Pricing
from $0.35 / 1,000 items
RSS & Atom Structured Feed Extractor
Point at ANY RSS or Atom feed (news, blogs, podcasts, GitHub releases, YouTube) and get clean structured rows. Auto-detects RSS 2.0 / RSS 1.0 / Atom and normalizes every entry to one schema: title, link, content, author, categories, ISO-8601 dates, enclosures. Pay per item.
Pricing
from $0.35 / 1,000 items
Rating
0.0
(0)
Developer
Datamule
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
23 days ago
Last modified
Categories
Share
Point at ANY RSS or Atom feed, get a clean structured dataset. One actor turns every feed on the web — RSS 2.0, RSS 1.0 (RDF) and Atom 1.0 — into the same normalized rows. No per-site scraper, no dialect wrangling.
RSS / Atom is the universal syndication format. News organizations, blogs, podcasts, GitHub releases, status pages, government notices, journal tables-of-contents and YouTube channels (Atom) all publish it. Give this actor a feed URL and it detects the dialect and flattens every entry into one consistent schema.
What it does
Fetches the feed, auto-detects the dialect, and normalizes every entry to one row shape regardless of whether the source is RSS or Atom:
| Field | Notes |
|---|---|
title, link, guid | RSS <link> text and Atom <link rel="alternate" href=> both resolve to link. |
summary | RSS <description> / Atom <summary>. |
content, contentType | Full text: RSS content:encoded / Atom <content> (toggle with fullContent). |
author, authorEmail, authorUri | Includes Dublin Core dc:creator. |
categories[] | Merges RSS <category>, Atom <category term=> and dc:subject. |
publishedAt, updatedAt | Normalized to ISO-8601 UTC — parsed from RFC-822 (RSS pubDate) and RFC-3339 (Atom). The raw strings are kept in publishedRaw / updatedRaw. |
enclosures[] | Podcast / media {url, type, length}. |
mediaThumbnails[], mediaContent[] | Media RSS (media:thumbnail / media:content). |
itunes* | Podcast fields (duration, episode, season, author, explicit, image). |
commentsUrl | RSS <comments>. |
Every row is also stamped with the feed-level envelope — feedTitle, feedLink,
feedDescription, feedLanguage, feedUpdated, generator — plus provenance
(_feedUrl, _dialect = rss2 / rdf / atom, _rowIndex) and a lossless _raw of
the full parsed entry.
The parse is the point. Real feeds omit most optional elements (a plain RSS item may
carry only title + link + date; a GitHub Atom entry has <updated> but no <published>),
so every field is read by node presence and is nullable — an absent element is null,
never a crash or a shifted column.
Input
| Field | Description |
|---|---|
feedUrl | An RSS or Atom feed URL, e.g. https://feeds.bbci.co.uk/news/rss.xml. Required unless feedUrls is given. |
feedUrls | Optional: harvest several feeds in one run. Each row is tagged with its _feedUrl. |
maxItems | Optional global cap on rows across all feeds (one billable event per row). |
fullContent | Include the full-text body when present (default true). |
userAgent | Optional override. A descriptive User-Agent is sent by default — some feeds 403 a blank / generic UA. |
timeoutSecs | Optional read timeout (default 60s). |
bearer / extraHeaders | Optional, for auth-gated feeds. Never required, never logged. |
Examples
A single news feed:
{ "feedUrl": "https://feeds.bbci.co.uk/news/rss.xml" }
Harvest several feeds at once (mixed dialects):
{"feedUrls": ["https://feeds.bbci.co.uk/news/rss.xml","https://hnrss.org/frontpage","https://github.com/apify/apify-sdk-python/releases.atom"],"maxItems": 200}
A YouTube channel (Atom) or a podcast feed works the same way — just pass the feed URL.
Resilience
A feed that returns a 4xx/5xx, times out, serves a non-feed body (an HTML error / anti-bot
page) or malformed XML that is not a recognizable feed is skipped with a warning and the
batch continues. A run where every feed is skipped fails so nothing broken ships. A
reachable feed with 0 entries yields 0 rows and a clean success (unpopular is fine; the
actor never fabricates rows). Feeds are parsed with the <!DOCTYPE> stripped first, so
external-entity (XXE) and billion-laughs payloads cannot expand.
Pricing
Pay-per-event: one item charge per emitted row.
Your max charge is respected. Rows are written only when your run's maximum charge
covers them, so every row in the dataset is billed and nothing past your budget is written.
If the budget runs out mid-feed the run stops cleanly with the rows you paid for; if it does
not cover even one item, no feed is requested at all. Set maxItems for an exact row count.