14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Twitterいいね画像定期保存Bot

Last updated at Posted at 2021-05-22

#イントロ

##ウマ娘っ!!
ケモミミストでありTwitterランドに生息している身としては
ウマ娘は今や生活必需コンテンツとなっている。
平日のお昼休み終了5分前、APEX初動落ち、
ありとあらゆるストレスを軽減する効力を持ち、いつかガンにも効くのは言うまでもないだろう。

尊い画像が無限に流れてくるTL、一つ一つの画像に合掌しているわけだが、
多すぎて見返せない。あれっ、ネイチャがトレーナー宅で同棲している激エモ漫画どこいった....
2次絵は一期一会、今保存しておかないと後々、神絵師垢が突然鍵垢にするかもしれないし、必ず見返せると保証できない。

##ゴール

  • いいねした画像を定期的にチェックして、保存するBotの運用
  • 保存した画像をGoogleフォトに保存、尊いアルバムを作成する

##対象読者

  • 自分のいいね欄の絵でアルバムを作ってニヤニヤしたい人

##非対象読者

  • TwitterAPIを使用するための導入手順が知りたい人
  • (はるか昔にdevアカウントを作っており、各種鍵が残ってたので今回はそれをそのまま使って作りました。私も今どうやって作るのか知りません... )

##最終的な運用システム
2021-05-23 (4).png

なんか図に起こすとややっこしいことやってるような気がする。
毎時自分の最新いいね200件を取得して、画像であれば保存しまくる。
GoogleフォトにももちろんAPIは存在していて、それを叩くともっとスマートなんだけど、

1.RaspiにGoogleフォトを操作するための認証を通す手順がダルそう
2.わざわざいいね画像を拝みに行くためにRaspiのネットワークドライブにアクセスするラグを俺が許容できない

以上の理由により、ローカルにも画像を同期しておいて、アクセスも早くお手軽に拝めるようにしたいな...
ってことでこうなってる。

本記事では①に関しての説明が主となる。

#事前準備フェーズ

##使用ライブラリなど

  • tweepy
    • twitterのAPIを簡単にキックできるようになるラッパー
HowToInstall
>pip install tweepy
  • exiv2
    • 画像のexifをコマンドで書き換えるために使う(使い所は後述)
HowToInstall
>sudo apt-get install -y exiv2

##Googleフォトにアップするにあたって
###課題
普段の写真とかもGoogleフォトにアップロードして管理しているので、
何千枚もあるTwitterのいいね画像で、現実の写真が埋もれるのは困る。
###対策
いいね画像のexif情報上の撮影日を大昔に設定して、Googleフォト上のタイムラインで事実上の区分けを行う。
今回はいいね画像は2000年1月1日に撮影されたものとしてGoogleフォトにアップロードして、
現実の写真と棲み分けする。
技術的にはexiv2を使って、画像のメタデータを編集する。
(exif情報を扱うため、Twitterから画像を保存する際は拡張子はpngではなく、jpgにする必要がある)

撮影日変更
>exiv2 -M 'set Exif.Photo.DateTimeOriginal "2000:01:01 08:00:00" "test.jpg"'

##Twitter APIについて
###GET favorites/list
サンプルとして、いいね欄最新2件を要求したときのレスポンスJSONを以下に示す。
(一部畳んで表示している)
2021-05-23 (8).png
.....つまり、extended_entities{}内のmedia[]プロパティ内に画像の情報があって、media_urlでjpgにアクセスできそう。

##仕様
###ファイル名フォーマットの決定

"ユーザ名__ツイートID.jpg"
にする。
もし、4枚画像がある場合、
"ユーザ名_ツイートID_0.jpg"~"ユーザ名_ツイートID_3.jpg"
として保存する。
これで、画像が投稿された実際のツイートにも行けるようにしておける。
ツイートURLは以下フォーマットで作成、アクセス可能。
https://twitter.com/i/web/status/ツイートID

#コード

いいねダウンローダ

import os
import pprint
import time
import urllib
import re

import tweepy

consumer_key ="XXXXX"
consumer_secret ="XXXXX"
access_token="XXXXX"
access_token_secret ="XXXXX"
 
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)

# 画像の撮影日を2000/01/01 00:00 に設定する
def setExifDate(img, date):
    command = "exiv2 -M \'set Exif.Photo.DateTimeOriginal \"" + date + "\"\' " + "'" + img + "'"
    print(command)
    os.system(command)

# URLから画像をダウンロードする
def download_file(url, dst_path):
    try:
        with urllib.request.urlopen(url) as web_file:
            data = web_file.read()
            with open(dst_path, mode='wb') as local_file:
                local_file.write(data)
    except urllib.error.URLError as e:
        print(e)

# 画像を保存するようのフォルダ作成
# 既に作成済みなら何もしない
try:
    os.makedirs("images/likes")
except:
    pass

# @hxbdy625のいいね欄から最新200件取得する、
likeList = api.favorites(screen_name='hxbdy625', count=200)

failue_tweet = []
dir_path = 'images/likes'
date = '2000:01:01 08:00:00'
for tweet in likeList:
    user  = tweet.user.screen_name
    page = 0
    print(user,':',tweet.id_str)
    try:
        # ツイートの内容にmediaエンティティが含まれている
        for data in tweet.extended_entities['media']:
            # 画像が2枚以上である場合、ファイル名の末尾に連番pageを付加する
            if(len(tweet.extended_entities['media']) > 1):
                if(data['type'] == 'photo'):
                    download_file(data['media_url'], '/'+dir_path+'/'+user+'_'+tweet.id_str+'_'+str(page)+'.jpg')
                    setExifDate('/'+dir_path+'/'+user+'_'+tweet.id_str+'_'+str(page)+'.jpg', date)
                    page += 1
      # 画像が1枚
            else:
                if(data['type'] == 'photo'):
                    download_file(data['media_url'], '/'+dir_path+'/'+user+'_'+tweet.id_str+'.jpg')
                    setExifDate('/'+dir_path+'/'+user+'_'+tweet.id_str+'.jpg', date)
    except AttributeError:
        msg = '[NotFoundImg] : https://twitter.com/i/web/status/'+ tweet.id_str+'\n'
        failue_tweet.append(msg)
        continue

f = open('error.txt','a')
f.writelines(failue_tweet)
f.close()

#実行結果
これを定期実行するとこんな感じで、Raspi内の保存フォルダ内に尊い画像が追加されていく。

このフォルダをGoogleの「同期とバックアップ」を使って、Googleフォトに自動アップロードする。
以下、Googleフォトでアップロードを確認できたときのスクショ。一部隠したけど。
2021-05-23 (6).png
ちゃんと2000/01/01になってる!

で、Googleフォト内でTwitter用のアルバムを作って、楽しむ(手動。ここ自動化できねぇのか?)
2021-05-23 (10).png

#参考
https://syncer.jp/Web/API/Twitter/REST_API/GET/favorites/list/

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?