特定のサイトが提供している情報を分析するために RSSからデータを取得するスクリプトを書いた。
XMLSlurper、GroovySQL、あとGroovyのクロージャのおかげで 結構シンプルに作成することができた。慣れたらもう少し Groovyらしいコードにできそう。
保存用のテーブル定義
create table entries ( id serial not null, site character varying(100), rssid character varying(100), title character varying(100), link character varying(255), published timestamp, updated timestamp, summary text, category character varying(255), content text, primary key(id) );
メインスクリプト
@Grapes([ @Grab(group='org.postgresql', module='postgresql', version='9.3-1102-jdbc41'), ]) import java.text.SimpleDateFormat import groovy.sql.Sql import org.postgresql.ds.PGSimpleDataSource def dbServer = '<DBサーバアドレス>' def dbName = '<DB名>' def dbPort = <DBポート番号> def dbUser = '<DBユーザー名>' def dbPass = '<DBパスワード>' //データベース接続 def sql = new Sql(new PGSimpleDataSource(serverName: dbServer, portNumber: dbPort, databaseName: dbName, user: dbUser, password: dbPass)) def url = '<Atom RSSのURL>' //Atom XMLを取得 def rss = new XmlSlurper().parse(url) //Atomの日付型に対応するフォーマット def dateFormat = new SimpleDateFormat('yyyy-MM-dd'T'HH:mm:ss'Z'') //println rss.title //println rss.updated def entryList = [] rss.entry.each { //カテゴリはカンマ区切りのテキストに変換 category = it.category.collect { it.@term.text() }.join(',') entryList.push([ id: it.id.text(), site: rss.title.text(), title: it.title.text(), link: it.link.@href.text(), published: dateFormat.parse(it.published.text()).toTimestamp(), updated: dateFormat.parse(it.updated.text()).toTimestamp(), summary: it.summary.text(), category: category, content: it.content.text() ]) } //重複チェック用にURLを抽出 def linkList = entryList.collect { ''${it.link}'' } //重複URLリストを生成 //GStringだと勝手にpreparedstatementに変換されてinがうまく動作しないので文字列結合を使用 def checkSql = 'select link from entries where link in (' + linkList.join(',') + ')' def dupLinkList = [] sql.eachRow(checkSql) { dupLinkList.push(it.link) } def insertSql = '' entryList.each {params -> //重複URLを除外してinsert if (!(params.link in dupLinkList)) { insertSql = 'insert into entries(rssid, site, title, link, published, updated, summary, category, content) ' insertSql += 'values(?, ?, ?, ?, ?, ?, ?, ?, ?)' sql.execute(insertSql, [ params.id, params.site, params.title, params.link, params.published, params.updated, params.summary, params.category, params.content ]) } }
このスクリプトを定期的に実行することで、RSSを収集できる。 1サイトからの収集にしか対応してないけど、URLをリスト化してループで 回せば複数サイト対応もすぐにできそう。
ハマったところは、
- Atomの日付型対応
- GroovySQLでのin検索
の2点。
GroovySQLはGStringでSQLを書くとGSQLという機能によって自動的に PreparedStatement化され、inの要素として渡した文字列も?変換されて うまく検索されないみたい。
Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築
- 作者: 綿引琢磨,須江信洋,林政利,今井勝信
- 出版社/メーカー: 翔泳社
- 発売日: 2014/11/07
- メディア: Kindle版
- この商品を含むブログ (2件) を見る