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

技術屋の末端。プログラミングも電気回路も専門外です。 コードに間違いなど見つけられたら、気軽にコメントください。 VC#、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