TwitterAPIを使ってみるテスト(by Python)

HappyNewYear
誰よりも早く?、今年初めの投稿です。(下書きしていたものだけど)


TwitterAPIを使ってみたいと思っています。
使う言語はJavaかPythonで迷ったけど、Pythonのほうが書きやすいと思い、Pythonを使うことにした。
(なんでJavaとPythonを候補にしたかというと、GoogleAppEngine上で何か作れないかな~って思うから)

とはいえ、Pythonで外部にアクセスしたことないので、まずは初歩的なことを試してみることにします。
やってみることは、「TwitterトレンドAPIにアクセスして、日々のトレンド情報取得」にしてみます。

具体的には、
(a)TwitterトレンドAPIにHTTPリクエスト送信
(b)JSON形式データの読込

を行ってみます。

使っている環境:
Python2.5.4
Windows7(64bit)


(1)はじめに
今回は、練習としてPythonの標準機能でできることを試してみるつもり。
なのでSDKは使いません。

OAuth認証とか、HTTPSアクセスとか行うときはSDKを使うことになると思う
ちなみに、TwitterAPIを使うときのSDKはこちらに公開されています。

Twitter Libraries

(注)
今回使うTwitterトレンドAPIは、API Version1.0をつかっています。
現状、Version1.1が提供されており、将来的にはVersion1.0は使えなくなると思います。
ただ今回は、Pythonの練習なので、OAuth認証が不要なVersion1.0を使うことにしました。


(2)TwitterトレンドAPI仕様確認

まず、マニュアルはこちら
GET trends/:woeid
GET trends/available

使い方は、
以下のような形式でリクエスト送信することで、データを受信できます。
「http://api.twitter.com/1/trends/:woeid.format」
ここでは、
:woeidには、 「Yahoo! Where On Earth ID」
.formatには、データ形式
になってる。
ためしに日本全体のトレンドを見てみる。ブラウザに
「http://api.twitter.com/1/trends/23424856.json」
と入力するとJSON形式でデータが返ってくる。

woeidはYahooが決めたものらしい。ID自体は世界中の地域に割り振られているようだが、Twitterトレンドで対応している地域が決まっているので、次にそれを確認する必要がります。

以下のアドレスにアクセスすると、利用できる地域の一覧がJSON形式で表示されます。(ちなみにマニュアルによるとxml形式もOKみたいなんだけど、試してみるとエラーになった。)
「http://api.twitter.com/1/trends/available.json」

まずは、この利用できる地域の一覧から、日本のID一覧をピックアップするものを作成してみることにします。
というわけで、次のコーディングに移ります。

(参考サイト)
TwitterトレンドAPIを使って最新のtwitterトレンドワードを取得してみる – yeyue’s diary:


(3)Pythonコーディング(GET trends/available)

PythonでHTTPリクエストを行うときは、ライブラリurllib2を使い、urlopenメソッドを使うらしい。

 urllib2.urlopen(URL)

試してみると確かにデータ取得できるんだけど、表示内容がすべて英語になってしまった。
ブラウザだと日本語になるのになんでかなって思ったんだけど、HTTPヘッダで指定してないからだって気付いた。

というわけで、HTTPヘッダに以下を追記することにします。
Accept-Language: ja,en

Pythonのコードは以下のような書き方になる。

            req = urllib2.Request(url)
            req.add_header('Accept-Language', 'ja,en')
            resultUrlOpen = urllib2.urlopen(req)

つぎにJSON形式データの読込です。
僕はPython2.5.*を使っているため、Python標準ライブラリにjsonモジュールが入っていませんでした。
(Python2.6以上では、標準で使える模様)
そのため、simplejsonというライブラリを使います。ただ、Python2.6以上でも、そのままつかえるように、ライブラリimport文を以下のように書いておきます。

try:
    import json
except ImportError:
    import simplejson as json

で、読込み(parse)は、jsonクラスのloadメソッドを使う。

results = json.load( JSON_DATA, encoding='utf8')

こうするとresultに、ハッシュ形式で格納される。(Pythonで言うとdictionary形式ですかね。

(参考サイト)
忘れがちな記憶へ Twitter Search API with Python

さて、コードをまるごと貼り付けておきます。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import os
import logging
import urllib2

try:
    import json
except ImportError:
    import simplejson as json

########################################

SEARCH_URL='http://api.twitter.com/1/trends/available.json'

def get_url():
    try:
        logging.info('get_url start')
        url=SEARCH_URL
        resultUrlOpen = None

        try:
            logging.info('url:%s', url)

            req = urllib2.Request(url)
            req.add_header('Accept-Language', 'ja,en')
            resultUrlOpen = urllib2.urlopen(req)
            return resultUrlOpen

        except urllib2.HTTPError:
            logging.warning('urllib2 HTTPError:%s', sys.exc_info())
            pass

        except urllib2.URLError:
            logging.warning('urllib2 URLError:%s', sys.exc_info())
            pass

        if None == resultUrlOpen:
            logging.error('resultUrlOpen==None')

        return None

    except:
        logging.error('get_url ERROR %s', sys.exc_info())
        raise

def read_json(wfp, resultUrlOpen):
    try:
        logging.info('read_json start')

        results = json.load( resultUrlOpen, encoding='utf8')

        if len(results) == 0:
            return

        HeaderText='%s,%s,%s,%s,%s' % ( 'name', 'placeType', 'country', 'woeid', 'countryCode')
        wfp.write('%s\n' % HeaderText.encode('utf-8')) #ファイル書き込み

        for result in results:

            line='%s,%s,%s,%s,%s' % ( result['name'], result['placeType']['name'], result['country'], result['woeid'], result['countryCode'])
            wfp.write('%s\n' % line.encode('utf-8')) #ファイル書き込み

        return
    except:
        logging.error('read_json ERROR %s', sys.exc_info())
        raise

if __name__ == "__main__":
    try:
#        logging.getLogger().setLevel(logging.ERROR)
        logging.getLogger().setLevel(logging.DEBUG)

        wfp = open('ret_tweet_trend_available.txt', 'w')

        resultUrlOpen = get_url()
        read_json(wfp, resultUrlOpen)

        wfp.close()

        logging.info('main end')
    except:
        print sys.exc_info()

実行すると、ret_tweet_trend_available.txtファイルに、CSV形式で一覧を出力します。

それをエクセルに貼り付けてフィルタしてみましたので、貼っておきます。

name    placeType    country    woeid    countryCode
北九州  Town         日本       1110809  JP
千葉    Town         日本       1117034  JP
福岡    Town         日本       1117099  JP
広島    Town         日本       1117227  JP
川崎    Town         日本       1117502  JP
神戸    Town         日本       1117545  JP
名古屋  Town         日本       1117817  JP
札幌    Town         日本       1118108  JP
仙台    Town         日本       1118129  JP
高松    Town         日本       1118285  JP
東京    Town         日本       1118370  JP
横浜    Town         日本       1118550  JP
沖縄    Town         日本       2345896  JP
大阪    Town         日本       15015370  JP
京都    Town         日本       15015372  JP
日本    Country      日本       23424856  JP

(4)Pythonコーディング(GET trends/:woeid)

日本のwoeid、23424856を使って、トレンド取得してみる。

やり方は、「GET trends/available」へアクセスしたときと同じなので、いきなりソースコードを貼り付けておきます。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import os
import logging
import urllib2

try:
    import json
except ImportError:
    import simplejson as json

########################################

SEARCH_URL='http://api.twitter.com/1/trends/23424856.json'

def get_url():
    try:
        logging.info('get_url start')
        url=SEARCH_URL
        resultUrlOpen = None

        try:
            logging.info('url:%s', url)

            req = urllib2.Request(url)
            req.add_header('Accept-Language', 'ja,en')
            resultUrlOpen = urllib2.urlopen(req)
            return resultUrlOpen

        except urllib2.HTTPError:
            logging.warning('urllib2 HTTPError:%s', sys.exc_info())
            pass

        except urllib2.URLError:
            logging.warning('urllib2 URLError:%s', sys.exc_info())
            pass

        if None == resultUrlOpen:
            logging.error('resultUrlOpen==None')

        return None

    except:
        logging.error('get_url ERROR %s', sys.exc_info())
        raise

def read_json(wfp, resultUrlOpen):
    try:
        logging.info('read_json start')

        results = json.load( resultUrlOpen, encoding='utf8')

        if len(results) == 0:
            return

        HeaderText='LocationName=%s,woeid=%s,created_at=%s' % ( results[0]['locations'][0]['name'], results[0]['locations'][0]['woeid'], results[0]['created_at'] )
        wfp.write('%s\n' % HeaderText.encode('utf-8')) #ファイル書き込み

        for trend in results[0]['trends']:
            line='%s' % ( trend['name'])
            wfp.write('%s\n' % line.encode('utf-8')) #ファイル書き込み

        return
    except:
        logging.error('read_json ERROR %s', sys.exc_info())
        raise

if __name__ == "__main__":
    try:
#        logging.getLogger().setLevel(logging.ERROR)
        logging.getLogger().setLevel(logging.DEBUG)

        wfp = open('ret_tweet_trend.txt', 'w')

        resultUrlOpen = get_url()
        read_json(wfp, resultUrlOpen)

        wfp.close()

        logging.info('main end')
    except:
        print sys.exc_info()

実行すると、ret_tweet_trend.txtファイルに、こんな感じで出力されます。

LocationName=日本,woeid=23424856,created_at=2012-12-31T19:16:32Z
今年もよろしく
おめでとうございます
Happy New Year
New Year
初日の出
お世話になりました
年越し
2012年
ジャニ
ありがとうございました

とりあえずこれで基本的なところは良しとして、今後もっと本格的にAPIを使ってみようと思う。


追記
TwitterAPIへのOAuth認証を試してみました。
TwitterAPIを使ってみるテスト2(OAuth) « Walk on apps.

Leave a comment