LoginSignup
2
4

More than 5 years have passed since last update.

TwitterのuserDataを取得

Last updated at Posted at 2017-05-14

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日たっても終わんない。。。

2
4
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
2
4