読者です 読者をやめる 読者になる 読者になる

ikarosの作業場

C#でWindows Store Appsやったり、Phunいじったり

Windows Store Apps(C#)でTwitterを使う:第四回

では前回加工のお話が上がりましたのでそのお話を
前回までやっていれば無事Twitterからなんかデータを得られたと思います

ではそのデータを加工してプログラムで使いやすい形にしてみましょう。

さてツイートなどTwitterから何か返ってきましたがそのデータはJSONと呼ばれる形式で書かれています。
つまりJSONデータを扱えるようにすればいいというわけです。

では私がこれまでやってきた失敗も含めながらお話を

失敗1:正規表現を使う
JSONデータもただの文字列ですから正規表現で真っ向から切り崩せるのではないかという安直な考え
Tweetsデータの中にはほかにUserフィールドなどがありTweetsオブジェクトと同じ名前のプロパティがあり、ツイートによってプロパティがあったりなかったりナノで
正規表現で切り崩すのはエラーがものすごく発生しやすいです。
ただ後述する方法でどうしてもそのままでは取得できない場合は私も正規表現を用いて取得しています。

失敗2:DynamicJsonを使ってtry-catchでデータを取得する
私がDynamicJsonの使い方を知らないだけかもしれませんが、動作が遅いことで知られるリフレクションを使うぐらいならとDynamicJsonで一回解析して
そこから考えうるすべての名前でtry-catchをやるという方法。今から考えるととても恐ろしい方法だったと思います。結局1ツイートを解析するのに2秒近くかかっていました。

ではどうするかというとC#の機能であるでシリアライザーを用います。
まずここを
Tweets | Twitter Developers
参考にTweetsフィールド同じ名前のプロパティを持つクラスを生成します

    [DataContract]
    public class Tweet
    {
        [DataMember]
        public string created_at { get; set; }

        public Tweet current_user_retweet;

        public Entity entities;

        [DataMember]
        public int favorite_count { get; set; }
        [DataMember]
        public bool favorited { get; set; }
        [DataMember]
        public string filter_level { get; set; }

        [DataMember]
        public decimal id { get; set; }
        [DataMember]
        public string id_str { get; set; }

        [DataMember]
        public string in_reply_to_screen_name { get; set; }
        //[DataMember]
        public decimal in_reply_to_status_id { get; set; }
        [DataMember]
        public string in_reply_to_status_id_str { get; set; }
        //[DataMember]
        public decimal in_reply_to_user_id { get; set; }
        [DataMember]
        public string in_reply_to_user_id_str { get; set; }

        [DataMember]
        public string lang { get; set; }

        public Place place;

        [DataMember]
        public bool possibly_sensitive { get; set; }

        [DataMember]
        public bool retweeted { get; set; }

        [DataMember]
        public int retweet_count { get; set; }

        public Tweet retweeted_status;

        [DataMember]
        public string source { get; set; }

        [DataMember]
        public string text { get; set; }
        [DataMember]
        public bool truncated { get; set; }

        public User user;

        [DataMember]
        public bool withheld_copyright { get; set; }
        [DataMember]
        public string[] withheld_in_countries { get; set; }
        [DataMember]
        public string withheld_scope { get; set; }

    }

[DataMember]とついている項目は大方Tweetsフィールドに入っていると思われるフィールドです
この[DataMember]がつけられたプロパティをJSON一斉に読み取っていきましょう

public static Tweet JsontoTweet(string result,OAuth user)
{
     Tweet a_tweet = new Tweet();
     DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(Tweet));

     MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(result));
     a_tweet = (Tweet)dcjs.ReadObject(stream);
}

これだけである程度速くJSONTweetというクラスに変換することができました。
あとはプロパティから情報を得てプログラムに組み込めますね。
ただし、ほかのUserフィールドはこのままでは読み取れないので正規表現でその部分を切り取ってまた同じように処理をしてあげる必要があります。


さて、ここまで書いてきたわけだがLINQとかでやる方法も魅力的ですよね・・・
それについては後ほど機会があれば書きたいと思います(まだ筆者が勉強中のため)

次回はいよいよ最終回となるのか・・・?StreamingAPIについて解説します

当サイトのソースコード及びその他の情報は個人・商用問わず自由に使っていただいてかかまいませんが、当サイトの情報が元で発生したいかなる結果・不利益については責任を負いかねますのでご了承ください