How to parse an RSS feed using JavaScript?

2019-01-01 14:58发布

问题:

I need to parse an RSS feed (XML version 2.0) and display the parsed details in an HTML page.

回答1:

Parsing the Feed

With jQuery\'s jFeed

(Don\'t really recommend that one, see the other options.)

jQuery.getFeed({
   url     : FEED_URL,
   success : function (feed) {
      console.log(feed.title);
      // do more stuff here
   }
});

With jQuery\'s Built-in XML Support

$.get(FEED_URL, function (data) {
    $(data).find(\"entry\").each(function () { // or \"item\" or whatever suits your feed
        var el = $(this);

        console.log(\"------------------------\");
        console.log(\"title      : \" + el.find(\"title\").text());
        console.log(\"author     : \" + el.find(\"author\").text());
        console.log(\"description: \" + el.find(\"description\").text());
    });
});

With jQuery and the Google AJAX Feed API

$.ajax({
  url      : document.location.protocol + \'//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&callback=?&q=\' + encodeURIComponent(FEED_URL),
  dataType : \'json\',
  success  : function (data) {
    if (data.responseData.feed && data.responseData.feed.entries) {
      $.each(data.responseData.feed.entries, function (i, e) {
        console.log(\"------------------------\");
        console.log(\"title      : \" + e.title);
        console.log(\"author     : \" + e.author);
        console.log(\"description: \" + e.description);
      });
    }
  }
});

But that means you\'re relient on them being online and reachable.


Building Content

Once you\'ve successfully extracted the information you need from the feed, you could create DocumentFragments (with document.createDocumentFragment() containing the elements (created with document.createElement()) you\'ll want to inject to display your data.


Injecting the content

Select the container element that you want on the page and append your document fragments to it, and simply use innerHTML to replace its content entirely.

Something like:

$(\'#rss-viewer\').append(aDocumentFragmentEntry);

or:

$(\'#rss-viewer\')[0].innerHTML = aDocumentFragmentOfAllEntries.innerHTML;

Test Data

Using this question\'s feed, which as of this writing gives:

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<feed xmlns=\"http://www.w3.org/2005/Atom\" xmlns:creativeCommons=\"http://backend.userland.com/creativeCommonsRssModule\" xmlns:re=\"http://purl.org/atompub/rank/1.0\">
    <title type=\"text\">How to parse a RSS feed using javascript? - Stack Overflow</title>
    <link rel=\"self\" href=\"https://stackoverflow.com/feeds/question/10943544\" type=\"application/atom+xml\" />
        <link rel=\"hub\" href=\"http://pubsubhubbub.appspot.com/\" />        
    <link rel=\"alternate\" href=\"https://stackoverflow.com/q/10943544\" type=\"text/html\" />
    <subtitle>most recent 30 from stackoverflow.com</subtitle>
    <updated>2012-06-08T06:36:47Z</updated>
    <id>https://stackoverflow.com/feeds/question/10943544</id>
    <creativeCommons:license>http://www.creativecommons.org/licenses/by-sa/3.0/rdf</creativeCommons:license> 
    <entry>
        <id>https://stackoverflow.com/q/10943544</id>
        <re:rank scheme=\"http://stackoverflow.com\">2</re:rank>
        <title type=\"text\">How to parse a RSS feed using javascript?</title>
        <category scheme=\"https://stackoverflow.com/feeds/question/10943544/tags\" term=\"javascript\"/><category scheme=\"https://stackoverflow.com/feeds/question/10943544/tags\" term=\"html5\"/><category scheme=\"https://stackoverflow.com/feeds/question/10943544/tags\" term=\"jquery-mobile\"/>
        <author>
            <name>Thiru</name>
            <uri>https://stackoverflow.com/users/1126255</uri>
        </author>
        <link rel=\"alternate\" href=\"https://stackoverflow.com/questions/10943544/how-to-parse-a-rss-feed-using-javascript\" />
        <published>2012-06-08T05:34:16Z</published>
        <updated>2012-06-08T06:35:22Z</updated>
        <summary type=\"html\">
            &lt;p&gt;I need to parse the RSS-Feed(XML version2.0) using XML and I want to display the parsed detail in HTML page, I tried in many ways. But its not working. My system is running under proxy, since I am new to this field, I don&#39;t know whether it is possible or not. If any one knows please help me on this. Thanks in advance.&lt;/p&gt;

        </summary>
    </entry>
    <entry>
        <id>https://stackoverflow.com/questions/10943544/-/10943610#10943610</id>
        <re:rank scheme=\"http://stackoverflow.com\">1</re:rank>
        <title type=\"text\">Answer by haylem for How to parse a RSS feed using javascript?</title>
        <author>
            <name>haylem</name>
            <uri>https://stackoverflow.com/users/453590</uri>
        </author>    
        <link rel=\"alternate\" href=\"https://stackoverflow.com/questions/10943544/how-to-parse-a-rss-feed-using-javascript/10943610#10943610\" />
        <published>2012-06-08T05:43:24Z</published>   
        <updated>2012-06-08T06:35:22Z</updated>
        <summary type=\"html\">&lt;h1&gt;Parsing the Feed&lt;/h1&gt;

&lt;h3&gt;With jQuery&#39;s jFeed&lt;/h3&gt;

&lt;p&gt;Try this, with the &lt;a href=&quot;http://plugins.jquery.com/project/jFeed&quot; rel=&quot;nofollow&quot;&gt;jFeed&lt;/a&gt; &lt;a href=&quot;http://www.jquery.com/&quot; rel=&quot;nofollow&quot;&gt;jQuery&lt;/a&gt; plug-in&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jQuery.getFeed({
   url     : FEED_URL,
   success : function (feed) {
      console.log(feed.title);
      // do more stuff here
   }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;With jQuery&#39;s Built-in XML Support&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;$.get(FEED_URL, function (data) {
    $(data).find(&quot;entry&quot;).each(function () { // or &quot;item&quot; or whatever suits your feed
        var el = $(this);

        console.log(&quot;------------------------&quot;);
        console.log(&quot;title      : &quot; + el.find(&quot;title&quot;).text());
        console.log(&quot;author     : &quot; + el.find(&quot;author&quot;).text());
        console.log(&quot;description: &quot; + el.find(&quot;description&quot;).text());
    });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;With jQuery and the Google AJAX APIs&lt;/h3&gt;

&lt;p&gt;Otherwise, &lt;a href=&quot;https://developers.google.com/feed/&quot; rel=&quot;nofollow&quot;&gt;Google&#39;s AJAX Feed API&lt;/a&gt; allows you to get the feed as a JSON object:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$.ajax({
  url      : document.location.protocol + &#39;//ajax.googleapis.com/ajax/services/feed/load?v=1.0&amp;amp;num=10&amp;amp;callback=?&amp;amp;q=&#39; + encodeURIComponent(FEED_URL),
  dataType : &#39;json&#39;,
  success  : function (data) {
    if (data.responseData.feed &amp;amp;&amp;amp; data.responseData.feed.entries) {
      $.each(data.responseData.feed.entries, function (i, e) {
        console.log(&quot;------------------------&quot;);
        console.log(&quot;title      : &quot; + e.title);
        console.log(&quot;author     : &quot; + e.author);
        console.log(&quot;description: &quot; + e.description);
      });
    }
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But that means you&#39;re relient on them being online and reachable.&lt;/p&gt;

&lt;hr&gt;

&lt;h1&gt;Building Content&lt;/h1&gt;

&lt;p&gt;Once you&#39;ve successfully extracted the information you need from the feed, you need to create document fragments containing the elements you&#39;ll want to inject to display your data.&lt;/p&gt;

&lt;hr&gt;

&lt;h1&gt;Injecting the content&lt;/h1&gt;

&lt;p&gt;Select the container element that you want on the page and append your document fragments to it, and simply use innerHTML to replace its content entirely.&lt;/p&gt;
</summary>
    </entry></feed>

Executions

Using jQuery\'s Built-in XML Support

Invoking:

$.get(\'https://stackoverflow.com/feeds/question/10943544\', function (data) {
    $(data).find(\"entry\").each(function () { // or \"item\" or whatever suits your feed
        var el = $(this);

        console.log(\"------------------------\");
        console.log(\"title      : \" + el.find(\"title\").text());
        console.log(\"author     : \" + el.find(\"author\").text());
        console.log(\"description: \" + el.find(\"description\").text());
    });
});

Prints out:

------------------------
title      : How to parse a RSS feed using javascript?
author     : 
            Thiru
            https://stackoverflow.com/users/1126255

description: 
------------------------
title      : Answer by haylem for How to parse a RSS feed using javascript?
author     : 
            haylem
            https://stackoverflow.com/users/453590

description: 

Using jQuery and the Google AJAX APIs

Invoking:

$.ajax({
  url      : document.location.protocol + \'//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&callback=?&q=\' + encodeURIComponent(\'https://stackoverflow.com/feeds/question/10943544\'),
  dataType : \'json\',
  success  : function (data) {
    if (data.responseData.feed && data.responseData.feed.entries) {
      $.each(data.responseData.feed.entries, function (i, e) {
        console.log(\"------------------------\");
        console.log(\"title      : \" + e.title);
        console.log(\"author     : \" + e.author);
        console.log(\"description: \" + e.description);
      });
    }
  }
});

Prints out:

------------------------
title      : How to parse a RSS feed using javascript?
author     : Thiru
description: undefined
------------------------
title      : Answer by haylem for How to parse a RSS feed using javascript?
author     : haylem
description: undefined


回答2:

Another deprecated (thanks to @daylight) option, and the easiest for me (this is what I\'m using for SpokenToday.info):

The Google Feed API without using JQuery and with only 2 steps:

  1. Import the library:

    <script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>
    <script type=\"text/javascript\">google.load(\"feeds\", \"1\");</script>
    
  2. Find/Load feeds (documentation):

    var feed = new google.feeds.Feed(\'http://www.google.com/trends/hottrends/atom/feed?pn=p1\');
    feed.load(function (data) {
        // Parse data depending on the specified response format, default is JSON.
        console.dir(data);
    });
    
  3. To parse data, check documentation about the response format.



回答3:

If you are looking for a simple and free alternative to Google Feed API for your rss widget then rss2json.com could be a suitable solution for that.

You may try to see how it works on a sample code from the api documentation below:

google.load(\"feeds\", \"1\");

    function initialize() {
      var feed = new google.feeds.Feed(\"https://news.ycombinator.com/rss\");
      feed.load(function(result) {
        if (!result.error) {
          var container = document.getElementById(\"feed\");
          for (var i = 0; i < result.feed.entries.length; i++) {
            var entry = result.feed.entries[i];
            var div = document.createElement(\"div\");
            div.appendChild(document.createTextNode(entry.title));
            container.appendChild(div);
          }
        }
      });
    }
    google.setOnLoadCallback(initialize);
<html>
  <head>    
     <script src=\"https://rss2json.com/gfapi.js\"></script>
  </head>
  <body>
    <p><b>Result from the API:</b></p>
    <div id=\"feed\"></div>
  </body>
</html>



回答4:

If you want to use a plain javascript API, there is a good example at https://github.com/hongkiat/js-rss-reader/

The complete description at https://www.hongkiat.com/blog/rss-reader-in-javascript/

It uses fetch method as a global method that asynchronously fetches a resource. Below is a snap of code:

fetch(websiteUrl).then((res) => {
  res.text().then((htmlTxt) => {
    var domParser = new DOMParser()
    let doc = domParser.parseFromString(htmlTxt, \'text/html\')
    var feedUrl = doc.querySelector(\'link[type=\"application/rss+xml\"]\').href
  })
}).catch(() => console.error(\'Error in fetching the website\'))