Twitterを活用したプログラムをC#で作成しよう
今回は、Visual Studio 2010 を使用して Twitter を活用するプログラムを作ってみましょう。
今やITに関係のない人であっても、様々な形で活用されている Twitter ですが、実際にやりとりされているデータは基本的なXMLファイルです。
したがって、XMLファイルから必要なデータを取り出したり、必要なXML形式のデータを生成したりといった技術を使えば、すぐに Twitter を活用したプログラムを作成することができます。
例えば、Twitter で標準的に表示されるタイムラインのデータですが、これは
https://twitter.com/statuses/friends_timeline.xml
として送信されています。
試しに、IEやFireFoxなどで、上記のURLを直接入力すると、ID・パスワードを聞いてくるのでそれを入力してユーザー認証したのちに、タイムラインを構成しているXMLファイルが表示されます。
まずは上記のようなXMLデータを、自分のプログラムから取得するコードを書いてみましょう。
C#でコンソールアプリケーションなどを選択し、以下のようなコードを入力します。
ただし入力する前に、プログラムの先頭に
using System.Net;
を追加してください。これによりWebClientクラスなどが簡単に使えるようになります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Net;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
WebClient myweb = new WebClient();
myweb.Credentials = new NetworkCredential("**ID**", "**password**");
byte[] pagedata = myweb.DownloadData("https://twitter.com/statuses/friends_timeline.xml");
Encoding ec = Encoding.UTF8;
Console.WriteLine(ec.GetString(pagedata));
}
}
}
なお、"**ID**" および "**password**" と書かれている部分には、ご自分のTwitterのIDとパスワードを入力してください。
これで実行すると、以下のように、タイムラインを構成するXMLファイルが表示されるはずです。
(ちなみに上記のTweetは私のテスト書き込みです。)
それでは次に、取得したXMLファイルの中から、必要な情報のみを取り出して表示することにします。
今のままですと、Tweetした一人一人の自己紹介などまで含まれてしまうため大変冗長ですし、そもそもXMLをエレメント単位に分割しなければそのデータを応用することができませんから、このステップは重要です。
XMLを解析するための方法は多数存在しますが、ここで使用させていただいたのは、XmlDocument クラスです。このクラスにはXML内のテキストデータを扱うための便利なメソッドが多数含まれており、比較的簡単に使うことができるので取り上げてみました。
流れとしては、LoadXml() を使用して先に取り込んだXMLデータを読み込み、その中から<Status>というエレメントで囲まれたものを一つのつぶやきデータとしてとらえて mylist に入れて、そのmylistの中から 表示したいデータ、ここでは Tweetしたユーザーの名前とそのTweetした内容、そして日時を表示する、という形になります。
以下がプログラムのコードです。Mainの中のみを紹介しています。
WebClient myweb = new WebClient();
myweb.Credentials = new NetworkCredential("**id**", "**password**");
byte[] pagedata = myweb.DownloadData("https://twitter.com/statuses/friends_timeline.xml");
Encoding ec = Encoding.UTF8;
string tag = "status";
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(ec.GetString(pagedata));
XmlElement root = xdoc.DocumentElement;
XmlNodeList mylist = root.GetElementsByTagName(tag);
for (int i = 0; i < mylist.Count; i++)
{
Console.WriteLine(mylist[i].ChildNodes[9].ChildNodes[1].InnerText); // User name
Console.WriteLine(mylist[i].ChildNodes[2].InnerText); // Tweet
Console.WriteLine(mylist[i].ChildNodes[0].InnerText); // posted time
Console.WriteLine();
}
この状態で実行すると、以下のようにかなり整理された形で表示されるはずです。
もう少し解説します。
forループに入る前の段階で、既にmylistの中にはすべてのXMLデータが取り込まれています。
mylist[0] には最新のTweetの情報が入っていますし、mylist[1] はその次のTweet情報・・というようにして、一番最後の mylist[ X ] にはそのタイムラインの中で一番古いTweet情報が入っていることになります。
各mylist[]の要素には、多数の子要素(ChildNodes)がぶら下がっています。
その中で、Tweetの本文はChildNodes[2]に入っていますので、mylist[i].ChildNodes[2].InnerText を表示させれば、Tweetの本文を表示することができるわけです。
同様に、mylist[i].ChildNodes[0].InnerText は投稿された時間です。
そしてユーザー名は若干ややこしくて、子要素のなかにさらに子要素があるという構造になっています。これは、ユーザー一人の持っている情報(例えばプロフィールやID、表示名など)が多いため、別のノード(枝)を用意してそこにユーザー情報を展開しているためです。ユーザー情報の元はmylist[i].ChildNodes[9]に入っていますが、さらにその下にぶら下がっている子要素の1番目にユーザー名が格納されているため、結局 mylist[i].ChildNodes[9].ChildNodes[1].InnerText がユーザー名を表すことになります。
さて、今回の最後のプログラムは、少しだけ上記のテクニックを応用して、現在のタイムラインの中で一番積極的にTweetしている人が誰なのかを調べるプログラムを作ってみましょう。
つまり、自分のタイムラインに登場するユーザー一人一人の、Tweetの回数をカウントしてリストとして表示するというものです。
方法は非常に原始的で、 UserNameというリストに対して、新規登場したユーザー名を追加していき、もしもその人のTweetがあったら、UserCountというリストの対応する位置の値を+1する、という流れになります。
List<string> UserName = new List<string>(); //to keep user names
List<int> UserCounter = new List<int>(); //to count how many posts are there for each user
WebClient myweb = new WebClient();
myweb.Credentials = new NetworkCredential("**ID**", "**password**");
byte[] pagedata = myweb.DownloadData("https://twitter.com/statuses/friends_timeline.xml");
Encoding ec = Encoding.UTF8;
string tag = "status";
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(ec.GetString(pagedata));
XmlElement root = xdoc.DocumentElement;
XmlNodeList mylist = root.GetElementsByTagName(tag);
for (int i = 0; i < mylist.Count; i++)
{
string CurrentUser = mylist[i].ChildNodes[9].ChildNodes[1].InnerText;
bool IsNewuser = true;
for (int j = 0; j < UserName.Count; j++)
{
if (UserName[j] == CurrentUser)
{
UserCounter[j]++;
IsNewuser = false;
}
}
if (IsNewuser == true)
{
UserName.Add(CurrentUser);
UserCounter.Add(1);
}
}
int k = 0;
foreach (string item in UserName)
{
Console.WriteLine(item + "さん : " + UserCounter[k].ToString() + "回つぶやき");
k++;
}
今回は、現状のタイムラインだけを加工するプログラムを紹介しましたが、もちろんこれ以外にも、Twitterは便利なAPIを多数公開しているので、次回はそれらをつかった更に便利なプログラムを紹介したいと思います。