絵師さんのTweetをRTするbotについて(3) - プロトタイプ
ファイル構成
仕様
※5分ごとに実行することを想定してTweetの読み込み件数等は割り当てている
1.既読履歴.jsonに記載されている最新のTweetまで、最大1000件のTweetを自分のタイムラインから読み込む
2.取得したTweetから絵付きTweetかつ自分がRTしたことのないものを探しリスト化する
3.絵付きTweetリスト.json内のリストと最新取得Tweetのリストを結合し、重複を除去する
4.結合したリストの中から最新のTweetを最大7件RTし除去する
5.リストを保存する
6.ログを出力する
現状わかっている問題点
- 5分間で1000Tweet以上TLが流れる場合取りこぼしが生じる可能性がある
- RT数の制限(投稿頻度の制限)が不明確なので確信が持てない
- 絵師さんがRTした関係ない絵付きTweetも拾ってしまうが、そこにノイズが多い。絵師さんが他の絵師さんの絵付きTweetをRTする場合にはそこまで拾えるという点でポジティブだが、現状ではノイズが目立つ印象になっている。
絵師さんのTweetをRTするbotについて(2) - 現状解決可能な問題として
作りたい機能:
絵師さんをフォローした状態のアカウントのTLを読み込み、絵付きのTweetをRTする。
制限:
home_timeline(自分のタイムライン)は最大3200Tweetまでの取得、15分で15回までの取得
user_timeline(特定のユーザーのTweet)は最大3200Tweetまでの取得、15分で180回までの取得
投稿は24時間で2400件、3時間で300件まで(推測)
頻度:
上記制限いっぱい
絵付きTweetとは何か?
Twitterに画像付きでアップロードされた投稿
必要な機能
1.API制限いっぱいの頻度で自分のタイムラインのうち最新の未読のものを取得
2.1で取得したTweetから絵付きTweetをリスト化し既存のリストと結合し更新
3.2で作成したリスト中のTweetをAPI制限いっぱいの頻度で最新のものからRT
4.3でRTしたTweetをリストから削除しリストを更新する
今後実装したい機能
・絵付きTweetをリスト化する際、同時に自分がRT済か判定する機能
ユーザーが自分の過去TweetをRTできるようになったことに伴い、既RTTweetが増えると思われるので、それに対応するため。
・user_timelineをユーザーごとに深掘りして絵付きTweetをリストに追加していく機能
home_timelineのAPI制限とuser_timelineのAPI制限は別なので、並列処理が可能なはず。途中から追加されたユーザーの以前のものやhome_timelineで取りこぼしてしまった絵付きTweetをすくいあげるのが狙い。
・他のユーザーが絵師さんのリストなどを作っている場合、そのリストがフォローしているユーザーをフォローする機能
・フォローしているユーザーがRTした絵付きTweetのオリジナルの投稿者をリスト化してフォローする機能
・user_timelineを深掘りしたユーザーの傾向を把握する機能
ユーザーのTweetのうちRTが自分の画像付きTweetの割合、頻度など。
Twitter APIでTLやuser_timelineをさかのぼるときの制限
tweepyの導入とpython対話型コンソール上での操作(6)
RTすべきTweetを探すのにフォローしている人を順々に当たる方法を考えていた。
つまり、
1.フォローしているユーザーそれぞれに取得済みTweetを把握する
2.フォローしているユーザーについて未取得Tweetを取得
3.2で取得したTweetから画像付きTweetを判定しRT
という方法にしようと思っていたが、
自分のTLをあたっていった方が速報性に優れるのではないか?ということで
自分のTLから探索する方法を考えた。
1.自分のTLのうち未取得のものを最新のものからn件取得する
2.1で取得したTweetから画像付きTweetを判定しRT
この場合、問題点になりうる箇所はいかのとおり
1.自分のRTを除外しないといけない
2.フォローしている人がRTしたものを除外したい場合どうすればいいか
3.新たにフォローした人の既読期間中の画像付きTweetが取りこぼしになってしまう
まず1の自分のRTを除外するのは
>>> a.retweeted
False
で容易に除外可能である。
次に2に関してはRTされたTweetには
>>>a.retweeted_status
Status(retweet_count=253, 以下略
というアイテムが記載されているのでそれでもって除外可能である。
最後の3に関してはそこまで完璧を目指すのは後からでもいいということで現時点ではスルー。もっとも、これもやる方法はなんとなく思いつくのでたぶん大丈夫。
Pythonで辞書や配列を操作する(tweepyで取得したデータも含めて)
自分のフォロー一覧を配列で取得する。
配列を辞書に格納する。
また、試しに出力してみる。
myID = api.me().id
fl = api.friends_ids(myID)
dicFollow = {}
dicFollow['IDs'] = fl
for id in dicFollow['IDs']:
print(id)
これでフォローのIDの一覧が出力されることを確認した。
tweepyでTweetを取得し、取得したTweetを対象にしてループを回す。
tempDict = api.user_timeline(id=dicFollow['IDs'][0], count=200)
for item in tempDict:
if 'media' in item.entities:
if item.entities['media'][0],get('type') == 'photo':
print (item.id)
ループの中でentities 内に 'media' keyが存在するか確かめ、存在する場合はそれがphotoであるか判定している。
tweepyの導入とpython対話型コンソール上での操作(5)
任意のユーザーのTweetを最新のものから任意の個数取得し、
取得した範囲を記憶し、次回取得時、
同じユーザーのTLを最新から前回取得した最新のものまで、
これまでに取得した最古のものの次から任意の個数まで、
取得する方法を調べる。
API Reference — tweepy 3.5.0 documentation
API.
user_timeline
([id/user_id/screen_name][, since_id][, max_id][, count][, page])
これを使うだけで良かった。
>>> tl=api.user_timeline('orenoyome', count=5)
>>> tlnew = api.user_timeline('orenoyome', since_id=tl[0].id)
>>> tlold = api.user_timeline('orenoyome', max_id=tl[len(tl)-1].id-1, count=5)
これで上記の必要は満たされた。
たぶんもっとかっこいいやり方はあるのだろうけれど。
最新のTweetがない場合、最古のTweetまで到達してなお古いものを取得しようとした場合、特にErrorは返されない。からっぽで帰ってくる。