twitterのフォロワー一覧にはscreen_nameしかないので、ユーザーidの情報をtwitterのフォロワー一覧に付与するということをしてました。
###Twitter API GET users/show
https://dev.twitter.com/rest/reference/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日たっても終わんない。。。