[追記] API 1.1の終了により、現在ではこの方法は使えません。
tweepy(GitHub: tweepy)は Python で Twitter API を呼び出すツールの一つ。
インストール:
pip install tweepy
まずは Twitter の Developer Portal の Dashboard でアプリケーション登録をする。
ここでは API 1.1 の Consumer Key,Consumer Secret,Access Token,Access Token Secret を使う方式について説明する。
ソースコードにこれらを直書きするのは危険なので、別の場所に保存する。例えば ~/.twitter.json
に次のように書いて、他人には読めないようにしておく:
{ "consumer_key": ".....", "consumer_secret": ".....", "access_token": ".....", "access_token_secret": "....." }
これを読み出すコード:
import json import os with open(os.path.expanduser("~/.twitter.json")) as f: token = json.load(f)
これを使って api を取得する:
import tweepy auth = tweepy.OAuth1UserHandler( token["consumer_key"], token["consumer_secret"], token["access_token"], token["access_token_secret"] ) api = tweepy.API(auth)
まずは「ホーム」タイムラインを取得してみよう:
home = api.home_timeline( # count=20, # デフォルト20ツイート取得 # since_id=1234567890123456789, # これより大きい # max_id=1234567890123456789, # これ以下 tweet_mode="extended") # 280文字対応
取得したツイートの表示例:
import datetime tz = datetime.timezone(datetime.timedelta(hours=9)) # JST for t in home: print(t.created_at.astimezone(tz).strftime('%Y-%m-%d %H:%M:%S'), t.id, t.user.screen_name) if hasattr(t, 'retweeted_status'): # リツイートなら t = t.retweeted_status # 元ツイート print(t.created_at.astimezone(tz).strftime('%Y-%m-%d %H:%M:%S'), t.id, t.user.screen_name) print(t.geo, t.coordinates, t.place) s = t.full_text s = s.replace("<", "<") s = s.replace(">", ">") s = s.replace("&", "&") for u in t.entities["urls"]: # t.coを元に戻す s = s.replace(u["url"], u["expanded_url"]) print(s) print("-" * 60)
特定の1ツイートだけでよければ次のように取得する:
t = api.get_status(1234567890123456789, tweet_mode="extended")
書き込みはこんな感じ(通常はツイート本文だけでよい):
media = api.media_upload("/path/to/image.jpg") # 添付メディアがある場合 status = api.update_status( "ツイート本文", # in_reply_to_status_id=1234567890123456789, # リプライ先 # auto_populate_reply_metadata=True, # リプライ先の @... を自動挿入 # attachment_url="https://twitter.com/.../status/...", # 引用リツイート media_ids=[media.media_id], # 静止画なら4つまで lat=34.7468, long=136.5248, display_coordinates=True, tweet_mode="extended") print("Tweeted:", status.id)
引用リツイートは従来のようにツイート本文末尾にURLを書いてもいいが,attachment_url="..."
で指定すると文字数カウントに入らない。リプライの先頭に付ける @...
も,手で書く代わりに auto_populate_reply_metadata=True
にすれば自動で入り,文字数カウントに入らない。
検索は次のようにする:
results = api.search_tweets( "検索クエリ", # 500文字以内 count=100, # 最大100、デフォルト15 result_type="recent", # or "popular" or "mixed" # lang="ja", # locale="ja", # max_id=1234567890123456789, # ≦ max_id # since_id=1234567890123456789, # > since_id # until="2022-12-31", tweet_mode="extended")
公式アプリでの検索と異なり、無料では7日分の検索しかできない。いずれにしても検索クエリに合致するツイートが全部取得できるわけではない。
また、リツイートされたものは重複して取得されてしまう。これが嫌なら、次のように、すでに取得されたものは表示しないための工夫が必要になる:
shown = set() for t in results: if hasattr(t, 'retweeted_status'): t = t.retweeted_status if t in shown: continue shown.add(t) # ツイートtを表示する
検索クエリの書き方については公式ドキュメント参照。ちなみに、公式アプリでの検索クエリについてはAdvanced Search on Twitterというガイドが参考になる。このガイドでは時刻指定の例は _UTC
となっているが、これを _JST
とすれば日本時間になる。例えば since:2022-11-19_01:23:45_JST until:2022-11-20_12:34:56_JST
のようにできる。リツイートも含めるには include:nativeretweets
とするが、これは7〜10日前までのツイートにしか適用されない。