【コピペでOK】Pythonの定期実行でツイート情報を大量取得

Pythonの定期実行でツイート大量取得

目次目次[閉じる]

この記事の目的

この記事は、PythonでTwitterの分析をすることを目的としています。

この内容は4部構成となっていて、今回は3番目の内容となっています。

全体の流れ
  1. Twitter APIの利用申請
  2. Tweepyでツイートを取得
  3. 定期実行でツイートの大量取得
  4. データの加工、分析・可視化

ツイート取得の流れ

今回の内容は以下の行程の続きとなっていますので、まだ見ていない方は↓こちらからどうぞ!

それはさっそくやっていきましょう!

定期実行の方法

定期実行の方法は以下のようにいくつか方法があります。

  • cron(UNIX/Linux系のPC)
  • タスクスケジューラー(windowsのみ)
  • scheduleモジュール

今回は3つ目の「schedule」というモジュールを使って定期実行を行います!

パパ
では、コードを見ていきましょう!

全体コード構成(コピペOK)

まずは、全体のコードです。コピペで動きます。

#ライブラリのインポート
import tweepy
from datetime import datetime,timezone
import pytz
import pandas as pd
import os #追加
import schedule #追加
from time import sleep #t

def main():

    #ターミナルに現在時刻を出力
    print(datetime.now())

    #Twitterの認証
    api_key = "****************************"
    api_secret = "*************************"
    access_key = "*************************"
    access_secret = "**********************"

    auth = tweepy.OAuthHandler(api_key, api_secret)
    auth.set_access_token(access_key, access_secret)
    api = tweepy.API(auth)

    #検索条件の設定
    searchkey = 'プログラミング'
    item_num = 10

    #検索条件を元にツイートを抽出
    tweets = tweepy.Cursor(api.search,q=searchkey,lang='ja').items(item_num)

    #抽出したデータから必要な情報を取り出す
    #取得したツイートを一つずつ取り出して必要な情報をtweet_dataに格納する
    tweet_data = []
    for tweet in tweets:
        #ツイート時刻とユーザのアカウント作成時刻を日本時刻にする
        tweet_time = change_time_JST(tweet.created_at)
        create_account_time = change_time_JST(tweet.user.created_at)
        #tweet_dataの配列に取得したい情報を入れていく
        tweet_data.append([
            tweet.id,
            tweet_time,
            tweet.text,
            tweet.favorite_count, 
            tweet.retweet_count, 
            tweet.user.id, 
            tweet.user.screen_name,
            tweet.user.name,
            tweet.user.description,
            tweet.user.friends_count,
            tweet.user.followers_count,
            create_account_time,
            tweet.user.following,
            tweet.user.profile_image_url,
            tweet.user.profile_background_image_url,
            tweet.user.url
                           ])

    #CSVファイルに出力するときの列の名前を定義
    labels=[
        'ツイートID',
        'ツイート時刻',
        'ツイート内容',
        'いいね数',
        'リツイート数',
        'ID',
        'ユーザID',
        'アカウント名',
        '自己紹介文',
        'フォロー数',
        'フォロワー数',
        'アカウント作成日時',
        '自分がフォローしているか?',
        'アイコン画像URL',
        'ヘッダー画像URL',
        'WEBサイト'
        ]

    #tweet_dataのリストをpandasのDataFrameに変換
    df = pd.DataFrame(tweet_data,columns=labels)

    #--- ここから新しい内容 ---

    #csvのファイル名
    file_name='tweet_data.csv'

    #カレントディレクトリを取得
    current_path = os.getcwd()

    #csvファイルの絶対パス
    file_path = os.path.join(current_path,file_name)
    #カレントディレクトリにtweet.csvが存在するか?
    file_check = os.path.isfile(file_path)

    #同じ名前のファイルがないとき
    if not file_check:  
        df.to_csv(file_name,encoding='utf-8-sig',index=False)
    #すでに同じファイルが存在しているとき
    else:
        #csvファイルの読み込み
        df_csv = pd.read_csv(file_name)

        #縦方向に-データフレームを結合
        df_merge = pd.concat([df_csv,df])

        #ツイートIDが重複しているものを削除
        df_merge = df_merge.drop_duplicates(keep='last',subset='ツイートID')

        #csvファイル出力
        df_merge.to_csv(file_name,encoding='utf-8-sig',index=False)

#関数: UTCをJSTに変換する
def change_time_JST(u_time):  

    #イギリスのtimezoneを設定するために再定義する
    utc_time = datetime(u_time.year, u_time.month,u_time.day, \
    u_time.hour,u_time.minute,u_time.second, tzinfo=timezone.utc)   # datetimeに変換(timezoneを付与)

    #タイムゾーンを日本時刻に変換
    jst_time = utc_time.astimezone(pytz.timezone("Asia/Tokyo"))

    #2021-09-26_17:19:20  という形式の文字列を返す
    str_time = jst_time.strftime("%Y-%m-%d_%H:%M:%S")

    return str_time


#main関数の実行
if __name__ == '__main__':

    #定期実行の設定
    schedule.every(20).minutes.do(main)

    #設定した定期実行を実行する
    while True:
        schedule.run_pending()
        sleep(1)

全体的な構成は以下のようになっています。

  • ライブラリのインポート
  • メインの処理:main()
  • JSTに変換する関数:change_time_JST()
  • 定期処理
パパ
それぞれについて解説していくよ!

コードの説明

ライブラリのインポート

#ライブラリのインポート
import tweepy
from datetime import datetime,timezone
import pytz
import pandas as pd
import os #追加
import schedule #追加
from time import sleep #追加

前回のコードと比較して新しく追加されたライブラリは以下の3つです。

  • os:ファイルのパスを取得
  • schedule:定期実行の実施
  • sleep:コードの実行を一時停止

今回のメインのライブラリは定期実行を行う「schedule」です。

インストールしていないライブラリは「pip install 〇〇」でインポートしましょう!

パパ
scheduleについては、後で丁寧に使い方を説明しますね!

メインの処理:main()

メインの部分は、大まかに以下のような流れになっています。

  1. Twitter APIの認証
  2. 検索条件設定・ツイート取得
  3. 情報の抽出・DataFrameに変換
  4. データの結合・CSVファイルに出力

4番目以外のコードについては前回とほぼ同じです。

パパ
前回と変わった部分を説明しますね!

まず、以下のコードでカレントディレクトリ(pythonファイルが置いてあるところ)にツイートデータが存在しているかを確認します。

#csvのファイル名
file_name='tweet_data.csv'
#カレントディレクトリを取得
current_path = os.getcwd()
#csvファイルの絶対パス
file_path = os.path.join(current_path,file_name)
#カレントディレクトリにtweet.csvが存在するか?
file_check = os.path.isfile(file_path)

最後の一文の .isfile()は、tweet_data.csvがすでに存在していれば"True"、存在しなければ”False"がfile_checkに代入されます。

あとは、以下のコードでfile_checkがTrueであればCSVファイルを読み込んで、新たに取得したデータを結合して上書き保存します。

file_checkがFalseであれば新規でCSVファイルを作成します。

#同じ名前のファイルがないとき
if not file_check:  
    df.to_csv(file_name,encoding='utf-8-sig',index=False)
#すでに同じファイルが存在しているとき
else:
    #csvファイルの読み込み
    df_csv = pd.read_csv(file_name)
    #縦方向に-データフレームを結合
    df_merge = pd.concat([df_csv,df])
    #ツイートIDが重複しているものを削除
    df_merge = df_merge.drop_duplicates(keep='last',subset='ツイートID')
    #csvファイル出力
    df_merge.to_csv(file_name,encoding='utf-8-sig',index=False)

また、このメインのコードは、main()という名前の関数にすることで定期実行できるようにしています。

あこ
何度も使うコードは関数にしてまとめると便利だね。

データの結合については、pandasのデータフレームのconcatというメソッドを使えば結合できます。

#縦にデータフレームを結合
df_merge = pd.concat([df_csv,df])

これによって、くり返し処理が実行されるたび、データが下に足されていくことになります。

定期実行

#main関数の実行
if __name__ == '__main__':

    #定期実行の設定
    schedule.every(20).minutes.do(main)

    #設定した定期実行を実行する
    while True:
        schedule.run_pending()
        sleep(1)

今回のメインの内容です!

「schedule」というモジュールの使い方をぜひ覚えてください!

使い方としては、大きく以下の流れになります。

  1. 定期実行の設定をする
  2. 設定した内容で実行する

定期実行の設定

scheduleを使うといろいろな設定ができます。

  • 一定時間ごとに実行する
  • 毎週月曜日の10時に実行する

今回では20分ごとにmain()の処理を実行する設定をしています。

定期実行のコードの意味

また、以下のようにすることで時間間隔も調整できます。

  • schedule.every(1) .weeks.do(main) => 1週間ごと
  • schedule.every(1) .days.do(main) => 1ごと
  • schedule.every(1).hours.do(main) => 1時間ごと
  • schedule.every(1).seconds.do(main) => 1 ごと

また、以下のように、曜日や時間指定をして実行することができます。

  • schedule .every().day.at("10:00") .do(main) => 毎日10:00
  • schedule .every().monday.at("10:00") .do(main) => 毎週月曜日10:00

このように自由に定期実行の設定ができますよ!

設定した内容で実行する

以下のコードで、定期実行を行います。

schedule.run_pending()

しかし、このコードだけでは不十分で、上記の処理を繰り返し実行することで定期実行が完成します。

繰り返し実行するためにはwhileを使います。 while 条件文: 繰り返しの処理

Whileは条件文がTrueである限り処理を繰り返します。 今回は条件文を「True」としているので、無限ループすることになります。

これらを合わせると

while True:
    schedule.run_pending()
    sleep(1)

これで定期実行の完成です! sleep(1)は、「1秒間止まる」を意味します。

Whileによる無限ループを一呼吸置きながら実行する、くらいに思ってもらえればOKです。

最後に

いかがでしたでしょうか?

あこ
定期実行もこれでばっちり!
パパ
定期実行は、自分に合う条件にしてやってみてね!

次のステップとしては、

ポイント
取得データの加工・分析

をやっていきます。

それでは!