【Python】特定ユーザのツイート取得および指定キーワードで抽出
やりたいこと
自分のツイートのうち、特定のハッシュタグつけたツイートのURLを一括で取得したい(Noteの読書記事に一括で貼り付けるため)
以下で作ったやつは直近7日分しか取得できない
結論
やりたいことはできるようになったが、Twitter API の仕様上取得できるのは直近100件までだった。
事前準備
Twitter API の利用申請 は過去記事参照。
利用するライブラリ
"requests_oauthlib" というライブラリを利用しているが、わたしの環境にはすでにインストールされていた。以前に tweepy をインストールしたときに勝手にインストールされたのかも?過去記事参照。
入ってない場合はインストール必要です。
>pip list
(一部抜粋)
Package Version
------------------ ---------
pip 22.2.2
pytz 2022.2.1
requests 2.28.1
requests-oauthlib 1.3.1
tweepy 4.10.1
作成したコード
import json
from requests_oauthlib import OAuth1Session
from pprint import pprint
from datetime import datetime,timezone
import pytz
import csv
import sys
sys.dont_write_bytecode = True # 自作モジュール apiKeys のキャッシュ作成させない
import apiKeys
# ★必要情報入力
keyword = "#夜は短し歩けよ乙女" # 検索ワード
tweet_max = 100 # 取得したいツイート数(5〜100まで)
# メイン関数
def main():
tl = getTL() # MY_ID のタイムラインのツイート情報を取得
results = storeTL(tl) # リスト[辞書{}] に格納しcsv書き出し
rslt_new = sorted(results, key=lambda x: x['created_at']) # 日時で昇順にソート
genTime = datetime.now().strftime('%Y年%m月%d日%H時%M分%S秒')
fileName = genTime + '_all.csv'
print("対象ユーザのツイート情報を書き出します。")
writeCsv(rslt_new, fileName) # csvファイルに出力
tekeoutTweet = takeoutKeyword(rslt_new) # キーワードで抽出
genTime = datetime.now().strftime('%Y年%m月%d日%H時%M分%S秒')
fileName = genTime + '_keyword.csv'
writeCsv(tekeoutTweet, fileName) # csvファイルに出力
print('本プログラムを正常終了します。')
# MY_ID のタイムラインのツイート情報を取得
def getTL():
MY_ID = apiKeys.TWITTER_ID
AK = apiKeys.API_KEY
AS = apiKeys.API_SECRET
AT = apiKeys.ACCESS_TOKEN
ATS = apiKeys.ACCESS_TOKEN_SECRET
twitter = OAuth1Session(AK, AS, AT, ATS)
url = f"https://api.twitter.com/2/users/{MY_ID}/tweets"
params = {
'expansions' : 'author_id',
'tweet.fields': 'created_at,public_metrics',
'user.fields' : 'name',
'max_results' : tweet_max,
}
res = twitter.get(url, params = params)
if res.status_code == 200:
tl = json.loads(res.text)
print("検索対象のアカウントは以下です。")
print(f" name : {tl['includes']['users'][0]['name']}")
print(f" user : {tl['includes']['users'][0]['username']}")
print('----------------------------')
else:
print("Failed: %d" % res.status_code)
return tl
# リスト[辞書{}] に格納
def storeTL(tl):
results = []
for tweet in tl['data']:
obj = {}
obj["tweet_id"] = tweet['id']
obj["text"] = tweet['text']
obj["created_at"] = change_time_JST(tweet['created_at']) # 投稿日時
obj["author_id"] = tweet['author_id']
for i in range(len(tl['includes']['users'])):
if tweet['author_id'] == tl['includes']['users'][i]['id']:
obj['user'] = tl['includes']['users'][i]['name']
obj['username'] = tl['includes']['users'][i]['username']
obj['tweetUrl'] = "https://twitter.com/" + tl['includes']['users'][i]['username'] + "/status/" + str(tweet['id'])
results.append(obj)
return results
def change_time_JST(u_time):
u_time = datetime.strptime(u_time, '%Y-%m-%dT%H:%M:%S.%fZ') # 文字列をdatetime型に変換
utc_time = datetime(u_time.year, u_time.month,u_time.day,
u_time.hour,u_time.minute,u_time.second, tzinfo=timezone.utc) #イギリスのtimezoneを設定するために再定義する
jst_time = utc_time.astimezone(pytz.timezone("Asia/Tokyo")) #タイムゾーンを日本時刻に変換
str_time = jst_time.strftime("%Y-%m-%d_%H:%M:%S") # 文字列で返す
return str_time
def writeCsv(data, fileName):
label = list(data[0].keys()) # 辞書のキー(ラベル)取得
with open(fileName, 'w', encoding='utf8', newline='') as f:
writer = csv.DictWriter(f, fieldnames=label)
writer.writeheader()
writer.writerows(data)
print(fileName + ' に書き出しました。')
print('----------------------------')
def takeoutKeyword(tl_data):
print("検索ワード「" + keyword + "」を含むツイートの情報のみ取り出します。")
tlText = [s for s in tl_data if keyword in s['text']]
return tlText
if __name__ == '__main__':
main()
本プログラムの概要
指定ユーザのツイートを取得し、指定したキーワードのツイート情報(URLなど)を抽出し csv ファイルに書き出す
Twitter API の仕様上取得できるのは直近100件まで。
本プログラムの詳細
TWITTER_ID で指定したユーザのツイート情報を tweet_max を上限に取得し、"*_all.csv" に出力する
tweepy の "search_recent_tweets" だと過去7日間分しか取得できなかったが、こちらはそのような制限ないみたい
取得したツイート情報から keyword の文字列を含むツイート情報のみを取り出し "*_keyword.csv" に出力する
取得したデータの中身は以下のような情報が入っている
'data': [{'author_id': '1130329021',
'created_at': '2022-09-11T12:17:34.000Z',
'id': '1568936789137838081',
'public_metrics': {'like_count': 0,
'quote_count': 0,
'reply_count': 0,
'retweet_count': 0},
'text': '成就した恋ほど語るに値しないものはない。\n\n俺なりの愛だ\n\n #四畳半神話大系 #アニメ'},
...
'includes': {'users': [{'id': '1130329021',
'name': 'lisy_すてかり',
'username': 'rissy_l'}]},
'meta': {'newest_id': '1568936789137838081',
'next_token': '7140dibdnow9c7btw4232twycqueobiyttcahjlqzwze8',
'oldest_id': '1566320934986076160',
'result_count': 5}}
参考にしたサイト
ツイート取得の参考
文字列の投稿日時を datetime に変換
特定文字列含む要素を取り出す
・Twitter ID の調べ方
実行結果
コンソール画面
検索対象のアカウントは以下です。
name : lisy_すてかり
user : rissy_l
----------------------------
対象ユーザのツイート情報を書き出します。
2022年09月18日17時58分27秒_all.csv に書き出しました。
----------------------------
検索ワード「#夜は短し歩けよ乙女」を含むツイートの情報のみ取り出します。
2022年09月18日17時58分27秒_keyword.csv に書き出しました。
----------------------------
本プログラムを正常終了します。
出力するcsvファイル(一部抜粋)
tweet_id,text,created_at,author_id,user,username,tweetUrl
1434052312243204097,~~,2021-09-04_16:14:49,1130329021,lisy_すてかり,rissy_l,https://twitter.com/rissy_l/status/1434052312243204097
終わりに(感想)
前回記事で利用した "search_recent_tweets" だと直近7日間分しか取得できず実用性低かったが、今回の API "get" はユーザ固定で直近100件まで取得できるので、やりたいこと(自分のツイートのうち、特定のハッシュタグつけたツイートのURLを一括で取得したい)の実現には十分だった。