AlfredWorkflowで遊ぶページ

Lesson14.RSSやHTMLをパースする/出力する一覧をコントロールする

サンプル動画

開発メモ

ワークフロー

1.パラメータで表示させる記事の一覧をコントロールさせるアイディア

 Alfredのアウトプットは9件表示させることができます
 でもニュースサイトなどのRSSの記事が9件以上あることもしばしば
 そこで、パラメータの文字数とページを紐づけることを考えました
 
 即ち
 ”rss a”というキーワードでサイトAのRSSの1件目から9件目を表示
 ”rss a+”と1文字”+”を追加したら、サイトAのRSSの10件目から18件目を表示
 ”rss a++”とさら”+”を追加したら、サイトAのRSSの19件目から27件目を表示
 
 もちろん、ここで
 ”rss a+”と”+”を削除したら、サイトAのRSSの10件目から18件目に戻るという風に
 
 実装の段階でrssは”rss a”から”rss z”の26種類としたので”+”ではなく、
 どの文字を続けて書いてもOKとしました。”rss kkk”みたいな続け打ちができます

2.パラメータで表示させる記事の一覧をコントロールを実装する

 出力するJSONフォーマットは、他のワークフローと同様に配列を利用して作成しています
 肝は入力パラメータの文字数(ページ数)と、ループさせる配列の添字を関連づけること
 入力パラメータの文字数は${#1}で取得できることが分かったので、あとは計算だけですね

 パラメータの文字数(ページ数) 1、 2、 3、 4、・・・
 各ページのトップ記事の添字   0、 9、18、27、・・・

 記事は9件分なので9回ループさせて配列からJSONフォーマットを作成すればOK
 ループのさせ方は色々あるかと思うので、どのような実装でもかまいません

3.ソースを解釈する( RSSパース)

 今回力技で26個のサイトRSSやHTMLをパースしたのですが、そのおかげで、
 grepやsedや配列が、なんとなく理解できました
 以下ポイントです

3-1.配列への代入はスペース区切りの文字列を括弧でくくるだけ

   hairetu=("foo" "bar" "bee" "boo") 


 とすると

   hairetu[0]に"foo"
   hairetu[1]に"bar"
   hairetu[2]に"bee"
   hairetu[3]に"boo"


 とそれぞれ格納されます
 
 そのためタグの情報をスペース区切りで取り出せば、簡単に配列とすることができます
 準備する配列は最低2つ。記事のタイトルと記事へのリンクです
 あとはサブタイトルとして記事の日付をいれることにしました
 
 イメージ(ブランクを△で明示しています)
 タイトル用配列 =(”タイトル1”△”タイトル2”△”タイトル3”…)
 リンク用配列 =(URL1”△”URL2”△”URL3”…)
 サブタイトル用配列 =(”日付1”△”日付2”△”日付3”…)
  
 ここで気をつけなければならないのは、取り出す情報の中にブランクがないこと
 ブランクがあると順番が狂ってしまい、抽出した情報間で整合性がとれなくなります
 (例えば、タイトルの個数・順番と、URLの個数・順番に不一致が生じで、
 同じ添字がつかえなくなっちゃうので)
 
 rss aのScriptFilterのコードをサンプルとして掲載し、以下で解説します

3-2.RSS情報を取得する

 curlで取得します。RSSでもHTMLでも同じです。ソースが受け取れます
 スクリプトをみると-sLのオプションが付いているものと、ついていないものがありますが、
 基本どっちでも良いです。というのも
 
 -sはサイレントの意味で余計なものは不要という指定です
 エラーを確認するような場合には外す方がよいかもしれませんが、
 パイプで後続に渡す時には、つけることがよくあるそうです
 
 -Lはリダイレクトを許可するオプションです
 リダイレクトするということはURLを変更した可能性があるので
 リダイレクトを許可せず、エラーとなったら確認するという方針でOKです
 
 オプションがバラバラなのは、表示できれば気にしないという方針ですので。悪しからず
 
 curlでソースを取得した後に、sedでスペースを削除しています
 上述のブランクが残ることによって配列が乱れることを防止するためです
 下記のコードです

  sed 's/ //g'

3-3.欲しい情報を取得する(コア)

 欲しい情報はタグの中身です。例えば記事のタイトルであれば、以下タグのxxxxxxの部分。

  <title>xxxxxx</title>


 基本的にgrepのoオプションで対象のタグを取り出します
 ちなみに、Eオプションは拡張正規表現の利用とのことですので、なんとなくつけたままです
 下記のようにするとソース内のすべてのタイトルタグをスペース区切りで取り出してくれます
 スペース区切りなので配列に格納するのにちょうどよいですね

  grep -oE '<title>[^<]+</title>'


 [^<]+というのは『<』以外の文字の連続を指定する部分がミソで、
 ここを任意の文字の連続とすると一番最後の</title>までがマッチします(全体で1個)
 
 次にsedで取り出します

  sed 's#<title>\(.*\)</title>#\1#'


 普通のsed sコマンドは/で区切るのですが#でもOKです
 今回は終了タグの/があるので、見易さを意識して#を使いまいした
 記号が3つあればOKらしく@を使った例もありますね
 
 タグの中身を取り出すためには括弧を使います
 置換対象の文字列はバックスラッシュのエスケープを外すとこんな感じ

  <title>(.*)</title>


 置換後の\1は1組目の括弧を意味しています(今回は1組しかないですが)
 つまり、sedの命令は、titleタグ全体をその中身の『.*』に置き換えるという意味になります
 
 なお最後にgがついていませんが、grep -oのパイプの場合はこれでOKです
 内部的な動きがあるのでしょう
 因みにgrepとsedを分ける場合はgをつけたり、Eオプションで正規表現にしたりする必要が
 ありました
 最後は配列への格納ですがスペース区切りになっているので、
 結果をそのまま括弧で括って変数に格納します

  title=(`xxxxx`)


 xxxxxの部分は上記のgrepやsedをechoしたもので、すでにスペースで区切られています
 スクリプトやAlfredのデバッグツールで確認してみてください(確認用のechoが必要ですが)

3-4.欲しい情報を取得する(バリエーションへの対応)

 RSSの場合は、記事のリンクはlinkタグ、日付はpubDateタグやdc:dateタグと
 ある程度ルールがあるようです
 HTMLの場合はCLASS指定を目印にするのがよいでしょう
 Aタグ、tdタグ、Hタグだけでは特定が困難で、配列に入れるための順序を保てないと思います
 
 rss f、rss h、rss m、rss v、rss xのスクリプトを見てもらえれば、力技の苦労がわかるかな
 ただ1度HTMLからの抽出に成功すると、他にもやりたくなってしまいます
 パズルのノリです

4.AlfredのJSONフォーマットを作成する

 情報が抽出できればあとはJSONを作るだけです
 titleは文字数が長いとAlfredの出力で『…』として中略されるので長さを制限しています
 linkはHTMLの場合相対パスで書いているものもあるので適宜補う必要があったりします
 subtitleは日付にしましたが物によって編集が必要です
 まあ大したことなないですね

5.苦労したことをすこしだけ

 基本的にカリカリとひたすらスクリプトを作りました
 ちょっと苦労したポイントです
 
 ・MedicalDOC
  RSSではなくHTMLをパースしています
 
 ・カラパイア
  もともと”rss k”で作成したのですがカラパイアのRSSが重たかったので一旦あきらめました
  その後まとめブログアンテナを発見HTMLでパースしてみました
  まだ、ちょっと反応遅いけど”rss x”として復活
 
 ・秒刊SUNDAY
  苦労ということでは無いですが、こちらも件数が多く重たいです 
 
 ・RSS F
  スクリプトの苦労ではないのですが、良さそうなRSSが発見できませんでした
  FNNプライムオンラインのニュースとしていましたが天気.jpのサプリ記事にしました
  Fから連想できない。。。
  HTMLをパースしていますが、タグの個数を合わせるために、いったん段落を抽出しています
  リンクのパスが相対パスでしたのでドメイン部分等追加しています
 
 ・オブジェクトが多い
  Script Filterをたくさん配置しています
  ロジックは同じようなものなのでコピペでつくったのですがピッタリ重なったりする
  ことがあります。隠れたオブジェクトが稼働しているとデバッグしにくいです
  (修正しても直らないという謎の現象が発生します)
  あと、間違ったオブジェクトに接続されるとおかしな動きをします
 
 以下、イニシャル文字と表示させるRSSの一覧です
  A: All About(新着記事)
    さまざまなジャンルの専門家によるコンテンツが充実した総合情報サイト
 
  B: 秒刊SUNDAY
   炎上を利用して人気を集めるブログ風ニュースサイト
 
  C: CREA
    知的好奇心旺盛な女性のためのこだわりの総合月刊誌CREAの公式サイト
 
  D: Daily News Agency
   世界で起こったもろもの面白いことを発信するニュースサイト
 
  E: ESSE (Yahoo rss)
   生活情報誌「ESSE」の記事と周辺情報をベースにした生活情報誌サイト
 
  F: 天気.jp サプリ記事
  日本気象協会公式サイトのコラム記事。季節の話題を提供
 
  G: GIZMODO
  メディアジーンが運営する日本最大のテクノロジー情報サイト
 
  H: ダ・ヴィンチニュース 人気の本・小説ランキング
  本のランキング。更新頻度はあまりないかな
 
  I: ITmediaニュース新着記事
  ソフトバンクグループ傘下のアイティメディアが運営するIT系ニュースサイト
 
  J: J-CASTニュース
  『Jカス』で検索ヒットするニュースサイト。カス丸くんがイメージキャラ
 
  K: goo急上昇ワード
  goo検索の急上昇ワード
 
  L: ねとらぼ
  ネット上の旬な情報を国内外からジャンルを問わず紹介する情報サイト
 
  M: MedicalDOC コラム
  多数のドクターと作った身近な医療情報サイト
 
  N: ナショナルジオグラフィック日本語版 
  品質の高い写真と自然科学の記事を配信するサイト
 
  O: 教えて!goo 最新の質問
  よろず相談サイトみんなの質問に答えましょう
 
  P: ネタとぴ
  やじうまネタ配信サイト
 
  Q: QJweb (Yahoo rss)
  1994年刊行の雑誌『クイック・ジャパン』から生まれたウェブニュースメディア
 
  R: ロケットニュース24
    くだらなくておもしろい出来事などを8割くらいの力で配信するサイト
 
  S: sorae (Yahoo rss)
  宇宙や天文のニュースを中心に『そら』に関する情報を提供するサイト
 
  T: TOCANA
  世の中の不思議やオカルトを集めたサイト。『ほんとかな』の『とかな』
 
  U: 虚構新聞
  個人が発信する嘘のニュースサイト。たまに嘘が本当になって誤報の謝罪があるとか
 
  V: ダ・ヴィンチニュース 毎日雑学
  書籍に関するニュース発信サイト。雑学コーナーの一覧ページをパースしてみました
 
  W: ついラン
  Twitterでのつぶやきの数を基にランキング
 
  X: カラパイ(まとめブログアンテナ)
  不思議と謎と超常現象のニュースサイト。未知を表すXで
 
  Y: zakzak by 夕刊フジ
  オレンジ色の憎い奴夕刊フジの公式ニュースサイト
 
  Z: Gigazine
  ギガジン=ギガバイト+マガジン。老舗ニュースサイト

    あー疲れた
 

背景

 nature remoのworkflowで”vol ++”を実装した時に思いつきました
 RSSの”rss +++”みたいな入力で、表示させる一覧のページ替えをさせたいなぁと
 多分Alfredで一番応用ができそうな使い方ではないかな
 あとAlfred出力フォーマットのアイコンで記事ごとの画像がのせられると良いかも 
 

取扱説明

機能:

 複数のRSSをパースして個々の記事の一覧をalfredの出力フォーマットに表示させる
 

インストール:

 1.Alfredworkflowをダウンロード
 2.ファイルをダブルクリックしてワークフローに登録

使い方:

 キーワード『rss x』で起動(xは任意の英字)
 xの後に何か文字を続けると、次の記事一覧を表示

修正履歴

Ver1.1(2021-03-28):

 ・ScriptFilterのJSONフォーマットの編集をワンライナーから1行1プロパティーに変更

 修正前の例

 json=$json'{"title":"'${title[i]:0:24}'","subtitle":"'${sub[i]:9:4}${sub[i]:6:3}${sub[i]:4:2}'","arg": "'${link[i]}'"}'


 修正後の例

  json=$json'{"title":"'${title[i]:0:24}'",'
  json=$json'"subtitle":"'${sub[i]:9:4}${sub[i]:6:3}${sub[i]:4:2}'",'
  json=$json'"arg": "'${link[i]}'"}' 


 ・ソースとは関係ありませんが、サンプル動画を投稿

ver1.2(2021-04-04):

 シェルスクリプトをbashからzshに変更

ver1.3(2021-04-24):

 ループ数の算出ロジックの誤りを修正(お恥ずかしい)
  誤) val2=$(($val1+9))
  正) val2=$(($val1+8))
  誤のロジックの場合、Alfred出力が10行になります
  そのままでは10行目は表示はされませんが、↓キーを押して行くと表示されます

ver1.4(2021-06-17):

 『rss v』を『goo ランキング』に変更
 以前は『ダ・ヴィンチニュース 毎日雑学』でしたが4月から更新がないので変更
 
トップページに戻る