[追記] 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日前までのツイートにしか適用されない。