プログラミング素人のはてなブログ

プログラミングも電気回路も専門外の技術屋の末端が勉強したことや作品をアウトプットするブログ。コードに間違いなど見つけられたら、気軽にコメントください。 C#、Python3、ラズパイなど。

tweepyでTwitterの画像検索

twitterは情報の宝庫です。
tweepyを使って「ねこ」の画像を集めてみたいと思います。
しかしながら、tweepy(twitter apiに無い)には画像を保存するメソッドが無いようなので、tweepyで画像のurlを取得してpythonのreqestsでアクセスして画像を保存します。

画像の保存の動きは↓を使わせてもらいました。
qiita.com

tweepyで検索を実行して、

for tweet in api.search(q=keyword, count=200):

Tweetの中にmediaがあるときに、mediaのurlを取得して、qiitaからいただいた関数にurlを渡します。

tweet.extended_entities['media'][0]['media_url']

tweepyではmedia(画像や動画)がないときにはこのKeyが無いので、本来ならこのkeyがあることを確認してからアクセスするべきですが、tryでくくることで省略しています。

この、extended_entitiesのkeyが変な構造になっていて、media keyのなかに要素が1のlistがあって、そのなかにmedia_urlのkeyがあります。

extended_entities={
'media':{
[
'media_url' :'http://pbs.twimg.com/media/hogehoge.jpg'
]
}
}

twitterapiのloginは関数を作っておくことで、別のpythonファイルにすることもできます。
importするような形にすることで、間違ってapi keyが流出することを防止できます。

login.pyとかにしておく。

def login(acount):
  if acount=="s51517765":
    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
    auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET)
    api = tweepy.API(auth)
    return api
  else:
    exit()

画像を保存するときは適当な連番をつけたりしないと、次々上書きされてしまいます。
数字(整数)を使って1~という方法が簡単ですが、これでは実行するたびに1~始まって上書きされてしまうので、日付と時刻を使うことでこれを防ぐことができます。
ただし、これでも1秒以内は同じ名前になって上書きされるので注意です。
ms(ミリ秒)までつかうという方法もありますが。

main.py

import login
import datetime
import tweepy
from datetime import datetime as dt
import time
import requests
import shutil

def download_img(url, file_name):
    r = requests.get(url, stream=True)
    if r.status_code == 200:
        with open(file_name, 'wb') as f:
            r.raw.decode_content = True
            shutil.copyfileobj(r.raw, f)

if __name__ == '__main__':
        keyword="ねこ"
        api=login.login("s51517765")
        for tweet in api.search(q=keyword, count=200):
            try:
                url=tweet.extended_entities['media'][0]['media_url']
                print(url)
                tdatetime = dt.now()
                filename='img/'+tdatetime.strftime('%Y%m%d%H%M%S')+'.jpg'  #"img"というサブフォルダに保存
                download_img(url,filename)
                time.sleep(1) #上書きされるので1秒待ってファイル名が変わるようにする
            except:
                pass #画像がないときはなにもしない

f:id:s51517765:20180217192131j:plain