Twitterでフォローされているがしていない人を調べるプログラムをScalaで作成した:100人乗っても大丈夫バージョン
前回 のプログラムはフォロワー、フレンドともに100人まで対応の手抜きバージョンだった。その後、なぜかフォロワーが100人を超えたため、より多くの人数に対応できるようにした。名付けて「100人乗っても大丈夫」バージョン。
TwitterFollowers.scala:
import scala.io.Source import scala.xml.XML object TwitterFollowers { def main(argv:Array[String]) { if (argv.length == 0) return val id = TwitterId(argv.first) val user = new TwitterUser(id) printNames("フォローしているが、されていない", user.friendsButNotFollowers) printNames("フォローされているが、していない", user.followersButNotFriends) } def printNames(title:String, names:TwitterNames) = { println(title) println(names.asString) println } } class TwitterUser(id:TwitterId) { val friends:TwitterNames = getFriends val followers:TwitterNames = getFollowers def friendsButNotFollowers = (friends - followers) def followersButNotFriends = (followers - friends) def getFriends = { val url = "http://api.twitter.com/1/statuses/friends/" + id.screenName + ".xml" TwitterNames(getNames(url)) } def getFollowers = { val url = "http://api.twitter.com/1/statuses/followers/" + id.screenName + ".xml" TwitterNames(getNames(url)) } def getNames(url:String) = { val names = getNamesIter(url, "-1") names.sort((s1, s2) => (s1 compareTo s2) < 0) } def getNamesIter(url:String, cursor:String):List[String] = cursor match { case "0" => List() case _ => { val pagingUrl = url + "?cursor=" + cursor val xml = getXml(pagingUrl) val names = (xml \\ "screen_name").map(_.text).toList val nextCursor = (xml \ "next_cursor").text names ::: getNamesIter(url, nextCursor) } } def getXml(url:String) = { val src = Source.fromURL(url) XML.loadString(src.getLines.mkString) } } case class TwitterId(screenName:String) case class TwitterNames(names:List[String]) { def -(other:TwitterNames) = TwitterNames(names.filter(!other.contains(_))) def asString = names match { case Nil => ""; case _ => names.reduceLeft{_ + "\n" + _}; } def contains(name:String) = names.contains(name) }
100人以上を取得するにはページング機能というものを有効にする。これはTwitter APIのURLの末尾に「?cursor=-1」を付ければよい。すると/users_list/next_cursorのテキスト部に次のページを取得するための値が返ってくるため、次回からはそれを「?cursor=値」として指定する。もし次ページが存在しないときは、next_cursorとして“0”が返ってくる。この動作はTwitterUserクラスのgetNamesIterメソッドが担当している。
よし、これでフォローされているがしていないユーザーを調べてフォローできるぞ! 将来的にはこれをWeb上で動かせるようにして、みんなで使えるようにしよう!と出来もしない野望に燃えていたところ、Refollow というサイトでフォロー関係を調べられることを発見。やっぱりなー。あると思ったんだ、Webサービス(^^;) というわけで、皆さんは Refollow を使ってくださいね。