キュレーション

https://kotobank.jp/word/%E3%82%AD%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-189130

IT用語としては、インターネット上の情報を収集しまとめること。

ということで、キュレーションサイトをキュレーションして楽に情報収集したい。 このエントリではその方法を模索する。

さしあたって、キュレーションするテーマは「DIY」ということにする。
なぜなら、私がDIYに興味があるから、です。

1. キュレーションサイトのピックアップ

まず適当にググる。
https://www.google.co.jp/search?q=diy+%E3%82%AD%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3
https://www.google.co.jp/search?q=diy+%E3%81%BE%E3%81%A8%E3%82%81

検索結果1ページ目のまとめサイトなどからキュレーションサイトを拾っていく。
サイト内検索があれば「DIY」検索したURLを控える。
RSSがあるものはそのURLを控える。

html

rss

こんな感じ。RSS対応してるサイト思ったより少ないなあ。時代の流れかしら。

2. データ取得

かき集めたサイトに対してそれぞれ処理して最終的な出力(json)にまとめよう。 jsonにできたらあとは好きな形にするだけなので今回はjsonにするところをゴールにする。

rssの処理

上記でrssがあるものについてはYQLでまとめてデータを取得しちゃう。

select title, link, date, pubDate from rss where url in (
  'http://b.hatena.ne.jp/search/text?safe=on&q=DIY&mode=rss',
  'https://hokuohkurashi.com/note/search/DIY/feed/rss2/',
  'https://limia.jp/feed/keywords/398',
  'https://makit.jp/cat2/feed/',
  'https://matome.naver.jp/feed/topic/1LwK5',
  'https://matome.naver.jp/feed/topic/1Lyni',
  'https://matome.naver.jp/feed/topic/1MCLj'
) order by date desc | unique(field="link")
curl -s  "https://query.yahooapis.com/v1/public/yql?q=select%20title%2C%20link%2C%20date%2C%20pubDate%20from%20rss%20where%20url%20in%20(%0A%20%20'http%3A%2F%2Fb.hatena.ne.jp%2Fsearch%2Ftext%3Fsafe%3Don%26q%3DDIY%26mode%3Drss'%2C%0A%20%20'https%3A%2F%2Fhokuohkurashi.com%2Fnote%2Fsearch%2FDIY%2Ffeed%2Frss2%2F'%2C%0A%20%20'https%3A%2F%2Flimia.jp%2Ffeed%2Fkeywords%2F398'%2C%0A%20%20'https%3A%2F%2Fmakit.jp%2Fcat2%2Ffeed%2F'%2C%0A%20%20'https%3A%2F%2Fmatome.naver.jp%2Ffeed%2Ftopic%2F1LwK5'%2C%0A%20%20'https%3A%2F%2Fmatome.naver.jp%2Ffeed%2Ftopic%2F1Lyni'%2C%0A%20%20'https%3A%2F%2Fmatome.naver.jp%2Ffeed%2Ftopic%2F1MCLj'%0A)%20order%20by%20date%20desc&format=json" | jq '.query.results.item' | python ./rss_consumer.py > a

curlの結果をjqに渡して結果部分を抽出する。 んで、データを見るとpubDateとdateの統一が取れなかったのでpythonで処理してやる。

#!/usr/bin/env python
import sys
import json
from datetime import datetime

_input = sys.stdin.read()
items = json.loads(_input, "utf-8")
for item in items:
    if "pubDate" in item:
        if "date" not in item:
            strdate = item["pubDate"]
            try:
                strdate = strdate.split("+")[0].strip()
                dt = datetime.strptime(strdate, '%a, %d %b %Y %H:%M:%S')
                strdate = dt.isoformat('T')+"Z"
            except:
                pass
            item["date"] = strdate
        del item["pubDate"]
items = sorted(items, key=lambda i: i["date"], reverse=True)
print json.dumps(items, sort_keys=True, ensure_ascii=False, indent=2).encode('utf-8');

htmlの処理

rssがないサイトについては面倒だけどもスクレイピング。
こちらもYQLを使いhtmlからjsonを取得する。
サイトの該当部分のxpathはChromeのデベロッパーツールで調べる。

select * from html where url = 'http://coyajoshi.com/article/diy/' and xpath = "//*[@id=recent_article]//li"

このサイトはこんな感じ。

curl -s  "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%20%3D%20'http%3A%2F%2Fcoyajoshi.com%2Farticle%2Fdiy%2F'%20and%20xpath%20%3D%20'%2F%2F*%5B%40id%3D%22recent_article%22%5D%2F%2Fli'%0A&format=json" | jq '.query.results.li | map({ link: .div[1].a.href, thumb: .div[1].a.img.src, date: .div[2].p.time.datetime, title: .div[2].h2.a.content }) | map(select(.link != null))' > b

同様にjqで整形してファイルに吐く。

jq -s '.[0] + .[1]' a b | jq 'unique_by(.link) | sort_by(.date, .pubDate) | reverse' > diy.json

複数のjsonを結合。

3. まとめ

そんな感じで最終出力の diy.json を得ることができました。
残りのhtmlについても同様にxpathで必要な部分を抜き出してjsonにしていきましょう。
………めんどくさいッスね。

まあ、でも実際にはinterfaceを用意してサイト毎に加工内容だけ差し替える感じで実装すればそんなに苦じゃない、かもしれない。

それにしてもYQLって便利やねー。

参考URL