[追記] API 1.1の終了により、現在ではこの方法は使えません。
こちらもどうぞ→ Twitter (tweepy)
本稿を書き始めた時点で Twitter libraries の Python の項の一番上にあった python-twitter を試してみた。現在は Twitter libraries のページは Tools and libraries にリダイレクトされる。PYPI の python-twitter のページは2018年で更新が止まっている。
インストールは
pip install python-twitter
でできる(パッケージ名は twitter になるので pip install twitter
で入る twitter パッケージとバッティングする)。
まずは Twitter のアプリケーション登録をする。方法は python-twitter's documentation にも書かれているし,日本語の解説もたくさんある(例えば Python3でTwitterAPIを使う方法をどのサイトよりも丁寧に解説する の前半)。
登録をしたら,Consumer Key,Consumer Secret,Access Token,Access Token Secret がもらえる。これらを次のコードの ...
の部分にコピペする。
試してみよう:
import twitter api = twitter.Api(consumer_key='...', consumer_secret='...', access_token_key='...', access_token_secret='...', tweet_mode='extended', sleep_on_rate_limit=True) api.VerifyCredentials() # 自分が正しく認識できているかチェック home = api.GetHomeTimeline() # ホームタイムラインを取得(デフォルト20件)
これで home
を表示すればだいたいの感じがわかる。このクラスの詳細は ??twitter.models.Status
と打ち込めば出てくる。この中の必要な項目を自分好みに出力すればよい。簡単な例を挙げておく:
for t in home: if (t.retweeted_status): t = t.retweeted_status for u in t.urls: t.full_text = t.full_text.replace(u.url, u.expanded_url) print(t.id, t.created_at, t.user.screen_name, t.full_text)
これを少しいじれば,自家製Twitterクライアントができる。これ以外に,位置情報 t.place
,正確な位置情報 t.geo
などが得られる。普段はEmacsのtwittering-modeを使っているが,自動処理にはコマンドラインで使えるほうが便利だ。
書き込みはこんな感じ(通常はツイート本文だけでよい):
api.PostUpdate("テスト", # ツイート本文(これだけ必須) media="hoge.jpg", # 添付画像ファイル(複数あればリスト) in_reply_to_status_id=1140050903828819970, # リプライ先のツイートID auto_populate_reply_metadata=True, # リプライ先の @... を自動挿入 attachment_url="https://twitter.com/.../status/...", # 引用リツイート latitude=34.7468, longitude=136.5248, # 位置情報 display_coordinates=True) # 正確な位置情報にするか
引用リツイートは従来のようにツイート本文末尾にURLを書いてもいいが,attachment_url="..."
で指定すると文字数カウントに入らない。リプライの先頭に付ける @...
も,手で書く代わりに auto_populate_reply_metadata=True
にすれば自動で入り,文字数カウントに入らない。
r = api.PostUpdate(...)
のように戻り値を取得すれば,例えば r.id
でツイートのIDが調べられる。ツイートをつなげていくときに便利。
毎時cronで起動して日毎のホームタイムラインをファイルにするコード例:
#! /usr/local/bin/python3 import twitter import time from dateutil.parser import parse from pytz import timezone api = twitter.Api(consumer_key='...', consumer_secret='...', access_token_key='...', access_token_secret='...', tweet_mode='extended', sleep_on_rate_limit=True) try: with open("maxid") as f: sid = int(f.read()) except: sid = 1 home = [] mid = None while True: h = api.GetHomeTimeline(count=200, since_id=sid, max_id=mid) home.extend(h) if len(h) < 150: break mid = home[-1].id - 1 if not home: exit() with open("maxid", "w") as f: f.write(str(home[0].id)) home.reverse() with open(time.strftime("%Y%m%d"), "a", newline="\n") as f: for t in home: if (t.retweeted_status): t = t.retweeted_status s = t.full_text for u in t.urls: s = s.replace(u.url, u.expanded_url) c = parse(t.created_at).astimezone(timezone('Asia/Tokyo')).strftime("%Y-%m-%d %H:%M:%S") print(t.id, c, t.user.screen_name, s.replace("\n", "\r"), sep="\t", file=f)
grepしやすいように1ツイート1行にするために,ツイート中の改行は "\r"
に変換している。
稀に h = api.GetHomeTimeline(...)
が失敗することがある。ゆっくり何度かやれば成功するみたいなので,この行を次で置き換えてみた:
cnt = 0 while cnt < 5: time.sleep(30) try: h = api.GetHomeTimeline(count=200, since_id=sid, max_id=mid) cnt = 10 except: h = [] cnt += 1
検索は python-twitter のドキュメントや,Twitter API の Search Tweets,Search Tweet Guides 参照。例:
import urllib.parse query = {"q": "ほげ ふが", # 検索文字列(スペース区切り) "result_type": "recent", # 新しいもの順に取得 "count": 100} # 最大100 results = [] while True: r = api.GetSearch(raw_query=urllib.parse.urlencode(query)) print('Retrieved', len(r), 'tweets') if len(r) == 0: break results.extend(r) query['max_id'] = results[-1].id - 1 time.sleep(1)
この方法で取得できるものは,検索語によっては,大部分が重複(リツイート)である。
結果をMeCabで形態素解析し,名詞の出現頻度をグラフにしてみよう:
import MeCab import collections text = "" for t in results: if (t.retweeted_status): t = t.retweeted_status s = t.full_text for u in t.urls: s = s.replace(u.url, ' ') text += s + '\n' mecab = MeCab.Tagger() nodes = mecab.parseToNode(text) s = [] while nodes: if nodes.feature[:2] == '名詞': s.append(nodes.surface) nodes = nodes.next c = collections.Counter(s) stopwords={"こと","もの","さん","それ","たち","よう","そう", "ため","これ","どこ","ほう","とき","みたい","そこ", "of","the","RT","うち","あと","こちら","あたり","あら", "ところ","わけ","はず","たくさん","ほんと","すべて", "ツイッター","Twitter"} i = 0 mc = {} for k,v in c.most_common(): if len(k) > 1 and k not in stopwords: print(k, v) mc[k] = v i += 1 if i >= 30: break plt.figure(figsize=[5, 5]) plt.barh(range(len(mc),0,-1), mc.values()) plt.yticks(range(len(mc),0,-1), mc.keys()) plt.savefig('hist.png', bbox_inches="tight")