Upgrade to Pro — share decks privately, control downloads, hide ads and more …

何となくわかってきた Twitter API と仲良く付き合う方法 #apihack

何となくわかってきた Twitter API と仲良く付き合う方法 #apihack

6月7日(金) (Twitter) API 勉強会/API1.0告別式 @恵比寿 @engineyard_jp #apihack のトーク資料です。
http://www.zusaar.com/event/751003

KOMIYA Atsushi

June 07, 2013
Tweet

More Decks by KOMIYA Atsushi

Other Decks in Technology

Transcript

  1. 僕と Twitter API •2010 ~ 2011 年 •Twitter API (v1)

    を認証なしでひたすらしばく お仕事 •特定アカウントからのフォロー・フォロワー 関係をクローリングするなど •2012 年 ~ •Twitter API (v1 → v1.1) を OAuth 認証して ただただ殴るお仕事 •ツイートを蓄積して後から参照できるように するなど 9
  2. 僕と Twitter API •2010 ~ 2011 年 •Twitter API (v1)

    を認証なしでひたすらしばく お仕事 •特定アカウントからのフォロー・フォロワー 関係をクローリングするなど •2012 年 ~ •Twitter API (v1 → v1.1) を OAuth 認証して ただただ殴るお仕事 •ツイートを蓄積して後から参照できるように するなど Twitter API を利用して 情報を蓄積したり分析したり するお仕事をしてきました 10
  3. 今日お話すること •主に Java (& Twitter4J) を用いてツ イートをデータベースに蓄積するに あたって •「えっ何これ? こんな仕様ドキュメント

    に書いてないじゃん/食い違ってるじゃ ん…」 •「こんなデータが来るとは想定していな かった…」 的なことをゆるく語っていきます 11
  4. MySQL 特有の事情 CREATE TABLE status( id BIGINT PRIMARY KEY ,tweet

    VARCHAR(140) ); java.sql.SQLException: Incorrect string value: '...' for column 'col_name' at row 1 28
  5. MySQL 特有の事情 •絵文字(Unicode 追加面の文字)を 含むテキストを DB に格納するには utf8mb4 の文字エンコーディングを指 定する必要があり

    •かつ、絵文字は VARCHAR 4 文字分消 費するので x 4 した桁数が必要に •参考 •http://blog.k11i.biz/2012/11/utf-8-mysql- jdbc.html 29
  6. MySQL 特有の事情 CREATE TABLE status( id BIGINT PRIMARY KEY ,tweet

    VARCHAR(140) ) ENGINE InnoDB CHARSET utf8mb4; 30 # my.cnf (my.ini) ... [mysqld] character-set-server=utf8mb4
  7. 結論 •MySQL でツイートを蓄積するときは 絵文字の存在を考慮し、文字エンコー ディングと VARCAHR の桁数に注意し ましょう •CREATE TABLE

    (~) CHARSET utf8mb4; •character-set-server=utf8mb4 •※ツイートに限らず、「名前」や 「プロフィール」など、フリー入力欄 はすべて考慮する必要があります 31
  8. でも実際は public static void main(String[] args) throws TwitterException { Twitter

    twitter = TwitterFactory.getSingleton(); Status status = twitter.showStatus(342528279581949952L); System.out.println("文字数 " + status.getText().length()); char[] chars = status.getText().toCharArray(); System.out.println(chars[0] + " / " + (int)chars[0]); System.out.println(chars[1] + " / " + (int)chars[1]); } // 出力 文字数 280 a / 97 ̈ / 776 38
  9. でも実際は public static void main(String[] args) throws TwitterException { Twitter

    twitter = TwitterFactory.getSingleton(); Status status = twitter.showStatus(342528279581949952L); System.out.println("文字数 " + status.getText().length()); char[] chars = status.getText().toCharArray(); System.out.println(chars[0] + " / " + (int)chars[0]); System.out.println(chars[1] + " / " + (int)chars[1]); } // 出力 文字数 280 a / 97 ̈ / 776 // 出力 文字数 280 a / 97 ̈ / 776 39
  10. でも実際は public static void main(String[] args) throws TwitterException { Twitter

    twitter = TwitterFactory.getSingleton(); Status status = twitter.showStatus(342528279581949952L); System.out.println("文字数 " + status.getText().length()); char[] chars = status.getText().toCharArray(); System.out.println(chars[0] + " / " + (int)chars[0]); System.out.println(chars[1] + " / " + (int)chars[1]); } // 出力 文字数 280 a / 97 ̈ / 776 // 出力 文字数 280 a / 97 ̈ / 776 ä が a と̈ に分解されてたー \(^o^)/ 40
  11. でも実際は public static void main(String[] args) throws TwitterException { Twitter

    twitter = TwitterFactory.getSingleton(); Status status = twitter.showStatus(342528279581949952L); System.out.println("文字数 " + status.getText().length()); char[] chars = status.getText().toCharArray(); System.out.println(chars[0] + " / " + (int)chars[0]); System.out.println(chars[1] + " / " + (int)chars[1]); } // 出力 文字数 280 a / 97 ̈ / 776 // 出力 文字数 280 a / 97 ̈ / 776 ä が a と̈ に分解されてたー \(^o^)/ スペイン語を扱ってるとよく遭遇する? 41
  12. search/tweets を 呼び出しているとたまに出くわします •「status[“user”] が存在しないんですけど どういうこと!?」という現象 •今まで調べてきた限りでは以下の状況で発 生するようです 1. あるユーザ

    @a が “ほげほげ” とつぶやく 2. ユーザ @b がそれを RT する 3. @a がアカウントを削除する(された?) 4. “ほげほげ” で search/tweets すると、 @b の RT が検索に引っかかってしまう 46
  13. search/tweets を 呼び出しているとたまに出くわします •「status[“user”] が存在しないんですけど どういうこと!?」という現象 •今まで調べてきた限りでは以下の状況で発 生するようです 1. あるユーザ

    @a が “ほげほげ” とつぶやく 2. ユーザ @b がそれを RT する 3. @a がアカウントを削除する(された?) 4. “ほげほげ” で search/tweets すると、 @b の RT が検索に引っかかってしまう ツイートした人を表すオブジェクト 47
  14. 以下の書き方には要注意! QueryResult res = twitter.search(new Query().query("hoge")); for (Status s :

    res.getTweets()) { String userName = s.getUser().getName(); // 何かの処理… } 48
  15. 以下の書き方には要注意! QueryResult res = twitter.search(new Query().query("hoge")); for (Status s :

    res.getTweets()) { String userName = s.getUser().getName(); // 何かの処理… } ここで NullPointerException が 発生するかも \(^o^)/ 49
  16. まとめ 1. アプリケーションの登録に注意する 2. ヌル文字に負けない 3. 絵文字に負けない 4. NFD/NFKD に負けない

    5. ユーザが常に在るとは限らない 6. Twitter の screen_name が 最大 15 文字であるはずがない 62