見出し画像

Twitterでいいねした画像を自動保存する

Twitterでいいねした画像を自動で保存し続けたい記事です。

ぼくにとってTwitterの楽しみの1つは好きなアイドルやコスプレイヤの画像なんですよね。タイムラインを見ると撮影会の写真や自撮りした画像が流れてきて、毎日癒やされます。気に入ったものを手で保存したりしていたのですが、手間がかかるため、いいねした画像を自動で保存したいと考えました。

調べてみると、特定アカウントの画像やいいねした画像をダウンロードするtimgというサービスが見つかりましたが、複数回ダウンロードすると前回保存したものもまたダウンロードしてしまうことや、画像サイズが最大じゃないことなど気になる点がありました。他にもいろいろな方法でやってる方が見つかりますが、できるだけ自分の思い通りにやりたいし、単純にTwitter APIを試してみたいというのもあり、Pythonで自分でやってみることにしました。

具体的にやりたいのは、いいねしたツイートの画像を自動でローカルに保存することです。Twitter APIを使えばなんでもできるんじゃないかと思ってやり始めましたが実際は制限もあり、試しているうちにわかったことがいろいろあるので、それについて書いてみたいと思います。すでに使ってる人にとっては簡単な内容だと思います。

Twitter API実行時に認証のため4つのトークンが必要なので、まずは開発者アカウントを申請して審査を通過し、承認される必要があります。

Your Twitter developer account application has been approved!

では早速使ってみます。いいねをリクエストするURLはこれですね。GETすると自分がいいねしたツイートの情報がJSON形式で、投稿日時が新しい順に20個取れます。https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-favorites-list

GET https://api.twitter.com/1.1/favorites/list.json

しかし20個では足りません。全部取るにはどうすればいいでしょうか?countというパラメータに200まで設定できるので、1回の呼び出しで200個まで取れます。しかし200個でも足りません。もっと古いツイートを取るにはどうすればいいでしょうか?max_idというパラメータを指定すると、指定したIDと同じか、それより古いツイートを返してくれます。なので、

APIを呼び出す
一番小さいIDを確認する
max_idに一番小さいIDを設定してAPIを再度呼び出す
また一番小さいIDを確認する
...

と繰り返せば、どんどん古いツイートの情報を得ることができそうです。

APIの呼び出し頻度には制限があり、15分あたり75回です。ということは15分で75回実行すれば200x75=15000個取れて、次の15分でまた15000個取れて、と繰り返していけば全部取れるんじゃないかと思いました。しかしそうはいきません。どうやら遡れるツイート数自体に制限があるらしく、3000くらいが限界でした。Webクライアントで自分の古いいいねを見ようと思っても全部見れないのと同じようです。なお、古いいいねを全部見る方法は存在しないわけではなく、Twitterの全ツイート履歴ダウンロードを利用すると、画像はついてきませんが一覧を取得できます。

というわけで、日々新しくいいねしていくと、3000個よりも古いいいねがどんどん見れなくなってしまうことがわかりました(T_T)。なので、見れなくなってしまう前に、たとえば週1とかの頻度で定期的に実行しないといけないのです!

また、TwitterのWebクライアントだといいねした順で表示されますが、APIでは投稿日時順に取れました。なので、すごく古いツイートを新たにいいねしても、それが3000個より古いツイートだった場合は残念ながらこのAPIでは取れないことになります。

画像URLはJSONのextended_entities内のmedia配列内のオブジェクトのmedia_urlに書かれています。2014年まではTwitterの画像が1枚だったため、entitiesだけでしたが、現在は4枚まで投稿できるのでextended_entitiesを見る必要があります。https://developer.twitter.com/en/docs/twitter-api/v1/data-dictionary/overview/extended-entities-object

画像取得の実験をしていて、たまにJSONに画像URLが取れていないことがありました。調べたところ、ツイートの"text"がURLを含んでいたりと長いときに、末尾が「…」となって省略されてしまい、情報がすべて取れていないことがわかりました。省略されたことは、そのツイートオブジェクトに"truncated": trueというフラグが付いていることで確認できます。このような場合に省略せずに全文取得するには、API呼び出し時にtweet_mode=extendedというパラメータを与える必要があります。tweet_mode=extendedを使用すると、ツイートの文字列は"text"ではなく"full_text"に省略なしで格納されるようになり、extended_entitiesもちゃんと取れ、フラグは"truncated": falseに変わります。

まとめるとAPIの呼び出しはこんな感じになります。

GET https://api.twitter.com/1.1/favorites/list.json?count=200&max_id=1303429696810618883&tweet_mode=extended

これで画像のURLは取れますが、もう1つ注意点があります。media_urlにそのままアクセスすると画像のサイズがオリジナルより小さくなってしまうことがあります。大きなサイズの画像にアクセスするには(media_url):largeとする必要があります。

自分で実際使っている感想として、ここまでの議論で大事な点はおさえられてるのではないかと思います。漏れているとか、画像が小さい!といった問題が起きていないので。以上をふまえて書いたget_fav_image.pyは有料記事ですが、どのような動作をするか述べます。実行するには適当なフォルダfolder_hogeにget_fav_image.pyを置きます。

folder_hoge
  + get_fav_image.py

folder_hogeにカレントフォルダを移動し、get_fav_image.pyを1回実行すると次のように画像とログのフォルダが自動で作られます。

folder_hoge
  + get_fav_image.py
  + logs
        + session.txt (実行したセッション数が書かれるログ)
        + 00001_idlist.txt (セッション1で取得したツイートIDのリスト)
        + idlist_all.txt (全てのセッションで取得したツイートIDのリスト)
  + images
        + 00001 (セッション1で取得した画像のフォルダ)
              + 画像1
              + 画像2
              + 画像3
              ...

実行のたびにセッションIDが増えていきます。つまり、もう1回実行すると、00002_idlist.txt(セッション2で取得したツイートIDのリスト)と00002(セッション2で取得した画像のフォルダ)が作られます。

画像の名前は{user_screen_name}_{tweet_id}_{numbering}.{jpg or png}としています。numberingというのは1つのツイートに複数の画像があった場合に1、2、3と採番するためのものです。ファイル名からアカウント名とツイートIDがわかれば便利かなと思ってぼくはこうしてますが、好きなようにカスタマイズすれば良いと思います。

idlist_all.txtというログを出しているのは、これまでに画像を保存したツイートID一覧を覚えておき、同じ画像を何度も保存するのを避けるためです。つまり2回目以降のセッションでは、すでに保存した画像を保存しません。

1回の実行ではAPIを15回呼び出すようにしています。これは1回で取れるツイートが200個で、いいねを遡れる数の限界が3000程度であることをふまえた回数です。20回呼んでも意味がないのです。

上に述べたように、実行するためにはTwitterの開発者アカウントを取得し、Access Tokenを発行し、合計4つのトークンを、コード中に記載する必要があります。Twitter APIに興味なかったらこれだけで敷居高いですが^^;

API_KEY = "***"
API_KEY_SECRET = "***"
ACCESS_TOKEN = "***"
ACCESS_TOKEN_SECRET = "***"

また、requests_oauthlibなどのライブラリを使っていますので、必要なライブラリはpipで事前にインストールする必要があります。

動作確認環境はWindows10、Python 3.8.5で、継続的に問題なく便利に使っています。いいねした画像を1箇所に保存できて、まとめて見れるというのは楽しいです。たとえば特定のアカウントの画像が欲しいとか動画も欲しいとかやり方を変えたいとかあると思いますが、好きなようにカスタマイズして使っていただければと思います。バグや、使用したことによる損害については念のため免責でお願いします^^;

get_fav_image.py

この続きをみるには

この続き: 3,156文字

Twitterでいいねした画像を自動保存する

あのこね anoconne

300円

この記事が気に入ったら、サポートをしてみませんか?
気軽にクリエイターの支援と、記事のオススメができます!
note.user.nickname || note.user.urlname

.

ありがとう!
プログラミング、映像、漫画、曲作りに興味を持っています。
コメントを投稿するには、 ログイン または 会員登録 をする必要があります。