🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

RSS

RSS(Really Simple Syndication)はブログのエントリやニュースの見出し、標準のフォーマットの音声やビデオなどを発行するために使われるウェブフィードのフォーマットの集合体です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Q&A

解決済

1回答

3419閲覧

GASを使って最新のRSSを1件のみ取得したい。

spa

総合スコア52

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

RSS

RSS(Really Simple Syndication)はブログのエントリやニュースの見出し、標準のフォーマットの音声やビデオなどを発行するために使われるウェブフィードのフォーマットの集合体です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

0グッド

0クリップ

投稿2021/03/19 13:29

編集2021/03/20 05:47

前提・実現したいこと

GASを使ってRSSを取得したのですが、10件取得になってしまいます。
1件だけ取得するにはどうすればよいか、アドバイスよろしくお願いします。
(コードは他の方が制作したものを参考にさせていただいています。)

該当のソースコード

javascript

1function fetchTodayPosts(feedUrl) { 2 var feedUrl = "http://umamusu.blog.jp/index.rdf"; 3 var response = UrlFetchApp.fetch(feedUrl); 4 var rssXML = response.getContentText(); 5 var document = XmlService.parse(rssXML); 6 var root = document.getRootElement(); 7 var ns_rss = XmlService.getNamespace('http://purl.org/rss/1.0/'); 8 var ns_dc = XmlService.getNamespace('dc', 'http://purl.org/dc/elements/1.1/'); 9 var ns_atom = XmlService.getNamespace('http://www.w3.org/2005/Atom'); 10 var ns_rdf = XmlService.getNamespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#'); 11 var rootTagName = root.getName().toLowerCase(); 12 var entries = []; 13 // 記事のリストを取得 14 switch (rootTagName) { 15 case 'rdf': // 1.0 16 entries = root.getChildren('item', ns_rss); 17 break; 18 case 'feed': // atom 19 entries = root.getChildren('entry', ns_atom); 20 break; 21 case 'rss': // 2.0 22 entries = root.getChild('channel').getChildren('item'); 23 break; 24 default: 25 return false; 26 } 27 return entries.map(function(entry, index) { 28 var title; 29 var link; 30 var pubDate; 31 switch (rootTagName) { 32 case 'rdf': // 1.0 33 title = entry.getChild('title', ns_rss).getText(); 34 link = entry.getChild('link', ns_rss).getText(); 35 pubDate = entry.getChild('date', ns_dc).getText(); 36 break; 37 case 'feed': // atom 38 title = entry.getChild('title', ns_atom).getText(); 39 link = entry.getChild('link', ns_atom).getAttribute('href').getValue(); 40 pubDate = entry.getChild('published', ns_atom).getText(); // 普段はこっちの方を利用する 41 // pubDate = entry.getChild('updated', ns_atom).getText(); // 今回はQiita用にupdatedを利用する 42 break; 43 case 'rss': // 2.0 44 title = entry.getChild('title').getText(); 45 link = entry.getChild('link').getText(); 46 pubDate = entry.getChild('pubDate').getText(); 47 break; 48 } 49 Logger.log(title); 50 Logger.log(link); 51 Logger.log(pubDate); 52 53 return ''; 54 }).filter(function(item) { 55 return item !== ''; 56 }); 57 58} 59

### 追記 feedUrlのURLを入れ替えながら最新記事のタイトル、URL、日付を取得したい。
今の状態だと、1つのRSSにつき10件取得してしまう。
最新のもののみがほしい。

javascript

1function fetchTodayPosts(feedUrl) { 2 3//スプレッドシートB列に記載されているRSSのURLを取得する。 4 var sheets = SpreadsheetApp.getActive().getSheetByName("blog_rss2"); 5 for (let i = 1; i < sheets.getLastRow()+1; i++){ 6 var rss_url = sheets.getRange(i, 2).getValues(); 7 8 9 var feedUrl = rss_url; 10 var response = UrlFetchApp.fetch(feedUrl); 11 var rssXML = response.getContentText(); 12 var document = XmlService.parse(rssXML); 13 var root = document.getRootElement(); 14 var ns_rss = XmlService.getNamespace('http://purl.org/rss/1.0/'); 15 var ns_dc = XmlService.getNamespace('dc', 'http://purl.org/dc/elements/1.1/'); 16 var ns_atom = XmlService.getNamespace('http://www.w3.org/2005/Atom'); 17 var ns_rdf = XmlService.getNamespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#'); 18 var rootTagName = root.getName().toLowerCase(); 19 var entries = []; 20 // 記事のリストを取得 21 switch (rootTagName) { 22 case 'rdf': // 1.0 23 entries = root.getChildren('item', ns_rss); 24 break; 25 case 'feed': // atom 26 entries = root.getChildren('entry', ns_atom); 27 break; 28 case 'rss': // 2.0 29 entries = root.getChild('channel').getChildren('item'); 30 break; 31 default: 32 return false; 33 } 34 entries= entries.map(function(entry, index) { 35 var title; 36 var link; 37 var pubDate; 38 switch (rootTagName) { 39 case 'rdf': // 1.0 40 title = entry.getChild('title', ns_rss).getText(); 41 link = entry.getChild('link', ns_rss).getText(); 42 pubDate = entry.getChild('date', ns_dc).getText(); 43 break; 44 case 'feed': // atom 45 title = entry.getChild('title', ns_atom).getText(); 46 link = entry.getChild('link', ns_atom).getAttribute('href').getValue(); 47 pubDate = entry.getChild('published', ns_atom).getText(); // 普段はこっちの方を利用する 48 // pubDate = entry.getChild('updated', ns_atom).getText(); // 今回はQiita用にupdatedを利用する 49 break; 50 case 'rss': // 2.0 51 title = entry.getChild('title').getText(); 52 link = entry.getChild('link').getText(); 53 pubDate = entry.getChild('pubDate').getText(); 54 break; 55 } 56 return {'title':title,'link':link,'pubDate':pubDate}; 57 }).sort(function(a,b){ 58 aV=a['pubDate'] 59 bV=b['pubDate'] 60 if (aV< bV) { 61 return -1; 62 } 63 if (aV > bV) { 64 return 1; 65 } 66 return 0; 67 }); 68 69 for (const entrie of entries){ 70 console.log(entrie['title']); 71 console.log(entrie['link']); 72 console.log(entrie['pubDate']); 73 74 }; 75 } 76} 77

イメージ説明

追記2 下記を実行するとスプレッドシートB列に記述したRSSのURLを取得できる。これを応用して feedUrlを変えながら最新記事のみの情報を取得しようとしたが失敗。1つのRSSにつき10件ずつ、計50件取得されてしまう。

function aaaaa(){ var sheets = SpreadsheetApp.getActive().getSheetByName("blog_rss2"); for (let i = 1; i < sheets.getLastRow()+1; i++){ var rss_url = sheets.getRange(i, 2).getValues(); Logger.log(rss_url); } }

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

私、全然詳しくないんですが、spaさんのコード見ながらやってみた結果記載します。

GAS

1 entries= entries.map(function(entry, index) { 2 var title; 3 var link; 4 var pubDate; 5 switch (rootTagName) { 6 case 'rdf': // 1.0 7 title = entry.getChild('title', ns_rss).getText(); 8 link = entry.getChild('link', ns_rss).getText(); 9 pubDate = entry.getChild('date', ns_dc).getText(); 10 break; 11 case 'feed': // atom 12 title = entry.getChild('title', ns_atom).getText(); 13 link = entry.getChild('link', ns_atom).getAttribute('href').getValue(); 14 pubDate = entry.getChild('published', ns_atom).getText(); // 普段はこっちの方を利用する 15 // pubDate = entry.getChild('updated', ns_atom).getText(); // 今回はQiita用にupdatedを利用する 16 break; 17 case 'rss': // 2.0 18 title = entry.getChild('title').getText(); 19 link = entry.getChild('link').getText(); 20 pubDate = entry.getChild('pubDate').getText(); 21 break; 22 } 23 return {'title':title,'link':link,'pubDate':pubDate}; 24 }).sort(function(a,b){ 25 aV=a['pubDate'] 26 bV=b['pubDate'] 27 if (aV< bV) { 28 return -1; 29 } 30 if (aV > bV) { 31 return 1; 32 } 33 return 0; 34 }); 35 36 for (const entrie of entries){ 37 console.log(entrie['title']); 38 console.log(entrie['link']); 39 console.log(entrie['pubDate']); 40 } 41

これでentriesがソートされるので1番目を取得すればいいんじゃないでしょうか。

こんなのでいいのかなぁ…でも、なんか出来てる気がするんだけどどうなんでしょう。

(追記1)
entriesの1番目を習得するコード

GAS

1 console.log(entries[0]['title']); 2 console.log(entries[0]['link']); 3 console.log(entries[0]['pubDate']); 4

投稿2021/03/19 15:01

編集2021/03/20 06:08
xail2222

総合スコア1508

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

spa

2021/03/20 00:26

回答ありがとうございます!ちゃんと動いてくれました。 一度リストを取得してから一番上のものだけを使う、というような発想しかなかったので 大変助かりました。
spa

2021/03/20 02:40

すみません、改造したらまたつまずいてしまいまして、 教えていただけるとありがたいです。 先程教えていただいたコードで、rssのurlリストをスプレッドシートから取得して、 複数回フェッチしたいと考えているのですが、 これをやるとまた10個づつリストがでてきてしまいます。 お時間があれば、追加で教えていただけるとありがたいです。 よろしくお願いします。 function fetchTodayPosts(feedUrl) { //付け足した部分(B列にURLのリストがある状態) var sheets = SpreadsheetApp.getActive().getSheetByName("blog_rss2"); for (let i = 1; i < sheets.getLastRow()+1; i++){    var rss_url = sheets.getRange(i, 2).getValues(); var feedUrl = rss_url; var response = UrlFetchApp.fetch(feedUrl); var rssXML = response.getContentText(); var document = XmlService.parse(rssXML); var root = document.getRootElement(); var ns_rss = XmlService.getNamespace('http://purl.org/rss/1.0/'); var ns_dc = XmlService.getNamespace('dc', 'http://purl.org/dc/elements/1.1/'); var ns_atom = XmlService.getNamespace('http://www.w3.org/2005/Atom'); var ns_rdf = XmlService.getNamespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#'); var rootTagName = root.getName().toLowerCase(); var entries = []; // 記事のリストを取得 switch (rootTagName) { case 'rdf': // 1.0 entries = root.getChildren('item', ns_rss); break; case 'feed': // atom entries = root.getChildren('entry', ns_atom); break; case 'rss': // 2.0 entries = root.getChild('channel').getChildren('item'); break; default: return false; } entries= entries.map(function(entry, index) { var title; var link; var pubDate; switch (rootTagName) { case 'rdf': // 1.0 title = entry.getChild('title', ns_rss).getText(); link = entry.getChild('link', ns_rss).getText(); pubDate = entry.getChild('date', ns_dc).getText(); break; case 'feed': // atom title = entry.getChild('title', ns_atom).getText(); link = entry.getChild('link', ns_atom).getAttribute('href').getValue(); pubDate = entry.getChild('published', ns_atom).getText(); // 普段はこっちの方を利用する // pubDate = entry.getChild('updated', ns_atom).getText(); // 今回はQiita用にupdatedを利用する break; case 'rss': // 2.0 title = entry.getChild('title').getText(); link = entry.getChild('link').getText(); pubDate = entry.getChild('pubDate').getText(); break; } return {'title':title,'link':link,'pubDate':pubDate}; }).sort(function(a,b){ aV=a['pubDate'] bV=b['pubDate'] if (aV< bV) { return -1; } if (aV > bV) { return 1; } return 0; }); for (const entrie of entries){ console.log(entrie['title']); console.log(entrie['link']); console.log(entrie['pubDate']); return 0; }; } }
xail2222

2021/03/20 04:04

えーっとよく理解できてないのですが「fetchTodayPosts」の戻り値を最新の1件にしたいということでしょうか。 であればreturn entries[0]でいいのだと思いますが。 どうなんだろう…
spa

2021/03/20 04:36 編集

fetchTodayPosts() を RSSのURLを変えて複数回行いたいのです。(今回は5個のURLをスプレッドシートに登録) 前回はRSSのURLのが「一つだけ」でしたが、今回はスプレッドシートから 複数URLを取得して、最新の1件のみを取得するのを繰り返したいです。 そこでfor文を使ってURLを入れ替えながら fetchTodayPosts() を回したのですが、1URLにつき10件ずつ取得されて合計50件になってしまいます。 これを最新の1件のみ取得し、全部で5件(1URLにつき最新の1件のみ)取得できるようにしたいです。 (for文を使うときは最後の return 0 を外しました。returnの使い方があまりよくわからないもので、ご迷惑おかけします。)
spa

2021/03/20 04:34 編集

http://aaaaaa.xml  ⇒最新の1件のみのタイトル URL 日付 を取得 http://bbbbb.xml  ⇒最新の1件のみのタイトル URL 日付 を取得 http://ccccc.xml  ⇒最新の1件のみのタイトル URL 日付 を取得  このような感じで取得できるようにしたいです。 いまは最新から10件ずつ取得されてしまうので改善したいです。 よろしくお願いします。
xail2222

2021/03/20 04:49 編集

全文を見ないと分からなさそうな感じです。あと、ここに追記だとインデントがわからないので質問に追記で現状のコードを記載してもらうといいんじゃないかと思う。 あと取得ってどういう意味ですか?ログに出ればいいという意味? 関数の戻り値になればいいという意味? ソースを見てるとreturn 0となってるので、取得と言ってる意味がよくわからないです。
spa

2021/03/20 05:50

説明がうまくいかなくてすみません。 追記したものでわかってもらえるかどうかわかりませんが、アドバイスよろしくお願いします。 取得の意味は、ログに出ればいいということです。 取得したものを再度スプレッドシートに書き込むことを想定しています。
xail2222

2021/03/20 06:04

「entriesがソートされるので1番目を取得すればいい」と記載しましたように entriesがソートされるので1番目、entries[0]のみで処理すれば1件目になります。 (追記1)にそのコードを記載しました。
spa

2021/03/20 06:15

ありがとうございました!無事解決です。 自分で試行錯誤した際は、 console.log(entrie['title'][0]); にしていました。完全に間違っていました・・・ お世話になりました。丁寧に回答していただきありがとうございます。
spa

2021/03/20 06:55

何度も申し訳ありませんが 先程のコード console.log(entries[0]['title']); console.log(entries[0]['link']); console.log(entries[0]['pubDate']); のあとすぐ下に取得結果を「スプレッドシートに書き込む」ために、 var sheets = SpreadsheetApp.getActive().getSheetByName("blog_rss2");  sheets.getRange(i,3).setValues(entries[0]['title']); sheets.getRange(i,4).setValues(entries[0]['link']); sheets.getRange(i,5).setValues(entries[0]['pubDate']); を追加したところ、 Exception: The parameters (String) don't match the method signature for SpreadsheetApp.Range.setValues. とエラーが出て書き込めない状態です。 原因がわかるようでしたら教えていただきたいです。
xail2222

2021/03/20 06:59

setValuesは、getRangeの範囲に2次元配列とかで値をセットする処理です。 単独の値でセットする場合はsetValueです。
spa

2021/03/20 07:11

ありがとうございます。 setValuesとsetValue 2種類あるのを知りませんでした。 調べてもなかなか出てこなかったので教えていただき感謝です。 いろいろとお世話になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問