TwitterのuserDataを取得


twitterのフォロワー一覧にはscreen_nameしかないので、ユーザーidの情報をtwitterのフォロワー一覧に付与するということをしてました。

Twitter API GET users/show

twitterフォロワーの一覧データ(csv)

name account followdate
久和 kazhu 2015/12/26
ぎり noko123 2015/12/26
太郎 taro123 2017/09/21

API制限 users/showは900件まで/15分

API制限が面倒なTwitterなのですが、回避の方法はコード7区の管理人さんの手法により。いつもありがとうございます。
TwitterAPI でツイートを大量に取得。サーバー側エラーも考慮(pythonで)

twitter_user_get.py

# coding=utf-8

import sys
import tweetkey
import os
from requests_oauthlib import OAuth1Session
import csv
import time
import json
import datetime


def init():

    # 各種キーをセットいつもの外部ファイルから
    CONSUMER_KEY = tweetkey.twkey['CONSUMER_KEY']
    CONSUMER_SECRET = tweetkey.twkey['CONSUMER_SECRET']
    ACCESS_TOKEN = tweetkey.twkey['ACCESS_TOKEN']
    ACCESS_SECRET = tweetkey.twkey['ACCESS_SECRET']

    twitter = OAuth1Session(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_SECRET)

    return(twitter)

def twittergetter(input_name,output_name,api):

    TweetIDList = []
    with open(input_name, 'r') as f:
        reader = csv.reader(f)
        header = next(reader)  # ヘッダーを読み飛ばしたい時

        # アウトプット用HEADにID列追加
        header.append("id")

        fout = open(output_name, 'wt')
        writer = csv.writer(fout)
        writer.writerow(header)

        for row in reader:
            #accountをcsvの配列2から取得して投げる
            screen_name = row[2]
            print(screen_name)
            url = "https://api.twitter.com/1.1/users/show.json?screen_name=" + screen_name
            # params = {'count': 100}
            # get_usersはパラメタなし
            req = api.get(url)

            if req.status_code == 200:
                users = json.loads(req.text)
                print(users)
                # userid はidにはいってら
                id = users["id"]
                print(id)
                # 帰ってきたidを配列に追加してwrite
                row.append(id)
                writer.writerow(row)

            else:
          # 404の時はscreen_nameがすでに変わっちゃってるか退会とかなのでそのままwrite
                if req.status_code == 404:
                    writer.writerow(row)
                else:
                    print ("Error: %d" % req.status_code)
                    time.sleep(240)

            # ヘッダ確認 (回数制限)
            # X-Rate-Limit-Remaining が入ってないことが稀にあるのでチェック
            if ('X-Rate-Limit-Remaining' in req.headers and 'X-Rate-Limit-Reset' in req.headers):
                if (int(req.headers['X-Rate-Limit-Remaining']) == 0):
                    waitUntilReset(int(req.headers['X-Rate-Limit-Reset']))
                    checkLimit()
            else:
                print('not found  -  X-Rate-Limit-Remaining or X-Rate-Limit-Reset')
                checkLimit()

        fout.close()
    return()


def checkLimit():
    '''
    回数制限を問合せ、アクセス可能になるまで wait する
    '''
    unavailableCnt = 0
    while True:
        url = "https://api.twitter.com/1.1/application/rate_limit_status.json"
        res = api.get(url)
        print(res.text)

        if res.status_code == 503:
            # 503 : Service Unavailable
            if unavailableCnt > 10:
                raise Exception('Twitter API error %d' % res.status_code)

            unavailableCnt += 1
            print('Service Unavailable 503')
            waitUntilReset(time.mktime(datetime.datetime.now().timetuple()) + 30)
            continue

        unavailableCnt = 0

        if res.status_code != 200:
            raise Exception('Twitter API error %d' % res.status_code)

        remaining, reset = getLimitContext(json.loads(res.text))
        if (remaining == 0):
            waitUntilReset(reset)
        else:
            break

def getLimitContext(res_text):
    '''
    回数制限の情報を取得 (起動時)
    '''
    remaining = res_text['resources']['users']['/users/show/:id']['remaining']
    reset = res_text['resources']['users']['/users/show/:id']['reset']
    print(reset)
    return int(remaining), int(reset)

def waitUntilReset(reset):
    '''
    reset 時刻まで sleep
    '''
    seconds = reset - time.mktime(datetime.datetime.now().timetuple())
    seconds = max(seconds, 0)
    print('\n     =====================')
    print('     == waiting %d sec ==' % seconds)
    print('     =====================')
    sys.stdout.flush()
    time.sleep(seconds + 10)  # 念のため + 10 秒

if __name__ == '__main__':
    api = init()
    input_name = os.getcwd() + "/twitterList.csv"
    output_name = os.getcwd() + "/twitterList_add_id.csv"
    twittergetter(input_name,output_name, api)

ただ、12万人のscreen_name変換しようとしたら2日たっても終わんない。。。