TwitterAPIを用いて、Pythonでデータ取得
Q&A
Closed
解決したいこと
Python初心者です。
大学の研究で、Xを研究対象にしています。
APIを申請したので、ある投稿にされたリツイートの情報を取り、CSVファイルに書き込むプログラムをhttps://www.topgate.co.jp/blog/techblog/4647
を参考にして、実行しようとしたのですが、エラーが出て、調べても解決できなかったので質問しました。
今回のコードは4つのキーで認証していますが、bearerトークンも所持しています。
APIの使用は今回が初めてです。
分かる方がいればよろしくお願いします。
発生している問題・エラー
ファイル名(例:retweet_info.csv):a.csv
--------送信するリクエスト数合計:1-------------
--------1回目。今回送信するリクエスト数:4--------------------
0:リクエストしたtweetID:XXXXXXXXXXXXXXXXXXX---------
Error: 401
Error数:1
該当するソースコード
from requests_oauthlib import OAuth1Session
import json
import csv
import collections as cl
import datetime,sys,time
file = input('ファイル名(例:retweet_info.csv):')
'''
OAuth認証
'''
def request_authorization (**url_and_params):
twitter = OAuth1Session(url_and_params['ck'], url_and_params['cs'], url_and_params['at'], url_and_params['ats'])
if('params' in url_and_params):
request_result = twitter.get(url_and_params['request_url'],params=url_and_params['params'])
else:
request_result = twitter.get(url_and_params['request_url'])
return request_result
'''
API制限をチェックし、制限解除までスリープ
'''
def sleep_until_api_limit(api_response):
sec = int(api_response.headers['X-Rate-Limit-Reset']) - time.mktime(datetime.datetime.now().timetuple()) #UTCを秒数に変換
sec += 60.0#念のため1分追加
print(str(sec)+"秒待機")
time.sleep(sec)
#取得した4つのkeyをここに差し込みます。
CK = "XXXXXXXXXXXXX" #Consumer key
CS = "XXXXXXXXXXXXX" #Consumer secret
AT = "XXXXXXXXXXXXX" #Access token
AS = "XXXXXXXXXXXXX" #Access token secret
global twitter#メソッド内で再認証を行うため
twitter = OAuth1Session(CK, CS, AT, AS)#認証処理。数時間すると認証が切れる。
# ツイート情報取得用エンドポイントURL
request_status_url = "https://api.twitter.com/2/tweets/:id/retweeted_by"
'''
情報を取得したいTweetIDをリストに格納
'''
tweet_id_list = ["TweetID"] #リツイート情報を取得したい TweetID をここに差し込みます。
tweet_id_list.sort()
total_requests_number = len(tweet_id_list)
print("--------"+"送信するリクエスト数合計:" + str(total_requests_number)+"-------------")
'''
TwitterからUserID情報の取得開始
'''
sched_requests_number = 0 #リクエストしたtweet_idの数
should_get_requests_limit = True #API上限数を取得するためのスイッチ
i_plus = 1 #API上限数を取得するためのスイッチ
requests_count = 0 #「API上限までリクエストを送る」を実行するのは何回目かカウントする用
error_count = 0 #エラーを返された回数をカウントする用
output_csv_file_name = file #取得した値を格納ファイル名
'''
ループ開始前にカラムへ書き込み
'''
with open(output_csv_file_name,'a') as f:
writer = csv.writer(f, lineterminator='\n')
header = ['tweet_id', 'retweet_id', 'user_id', 'created_at']
writer.writerow(header)
'''
ループ開始。retweet_idの書き込み。
'''
for i in range(0,total_requests_number,i_plus):
if(should_get_requests_limit == True):
api_response = request_authorization(request_url=request_status_url, ck=CK, cs=CS, at=AT, ats=AS)
requests_limit = api_response.headers['X-Rate-Limit-Remaining']#リクエスト可能残数の取得
requests_limit = int(requests_limit)#limitが文字列なのでキャスト
requests_count += 1
print("--------"+str(requests_count)+"回目。今回送信するリクエスト数:" + str(requests_limit)+"--------------------")
sched_requests_number += requests_limit
should_get_requests_limit = False
if(requests_limit != 0):
i_plus = 1
print(str(i) + ":リクエストしたtweetID:" + str(tweet_id_list[i])+"---------")
request_url = "https://api.twitter.com/2/tweets/"+str(tweet_id_list[i])+"?/retweeted_by/count=10&trim_user=false"
params = {'tweet_id':tweet_id_list[i]}
request_result = request_authorization(request_url=request_url, ck=CK, cs=CS, at=AT, ats=AS, params=params)
if request_result.status_code == 200:
tweetinfo = json.loads(request_result.text)#JSON形式で読み込む
for j in range(0,len(tweetinfo)):
print(str(i)+":"+str(j)+":"+"リツイートID" + str(tweetinfo[j]['id']))
followerdata = {'tweet_id':tweet_id_list[i],
'retweet_id':tweetinfo[j]['id'],
'user_id':tweetinfo[j]['user']['id'],
'created_at':tweetinfo[j]['created_at']}
with open(output_csv_file_name, 'a') as f:
writer = csv.writer(f, lineterminator='\n')
writer.writerow(followerdata.values())
else:
print ("Error: %d" % request_result.status_code)
error_count += 1
print("Error数:"+str(error_count))
else:
i_plus = 0 #limitが0のままiが1増えてしまうと実行されないTweeetIDが発生するので、0入れて増やさない。
if(i == sched_requests_number):
print("--------"+"残りリクエスト数" + str(total_requests_number-requests_limit) + "-------------")
sleep_until_api_limit(api_response)
should_get_requests_limit = True
自分で試したこと
調べながら、エンドポイントURLを変えたりしてみましたが、エラーが無くなりません。