RSS & Atom Structured Feed Extractor avatar

RSS & Atom Structured Feed Extractor

Pricing

from $0.35 / 1,000 items

Go to Apify Store
RSS & Atom Structured Feed Extractor

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

Datamule

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

23 days ago

Last modified

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:

FieldNotes
title, link, guidRSS <link> text and Atom <link rel="alternate" href=> both resolve to link.
summaryRSS <description> / Atom <summary>.
content, contentTypeFull text: RSS content:encoded / Atom <content> (toggle with fullContent).
author, authorEmail, authorUriIncludes Dublin Core dc:creator.
categories[]Merges RSS <category>, Atom <category term=> and dc:subject.
publishedAt, updatedAtNormalized 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).
commentsUrlRSS <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

FieldDescription
feedUrlAn RSS or Atom feed URL, e.g. https://feeds.bbci.co.uk/news/rss.xml. Required unless feedUrls is given.
feedUrlsOptional: harvest several feeds in one run. Each row is tagged with its _feedUrl.
maxItemsOptional global cap on rows across all feeds (one billable event per row).
fullContentInclude the full-text body when present (default true).
userAgentOptional override. A descriptive User-Agent is sent by default — some feeds 403 a blank / generic UA.
timeoutSecsOptional read timeout (default 60s).
bearer / extraHeadersOptional, 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.