Twitter API v2の使い方4[ユーザー情報取得編]

Twitter API v2の使い方4[ユーザー情報取得編]

Twitter API v2の使い方

Twitter API v2は大きく分けると2つ、

  • ツイート

  • ユーザー

2つの情報が取得できる。
以前はツイート検索をしたかったためツイート取得機能を使用した。

今回はユーザー情報に関する以下の機能を試す。

機能説明
User lookupユーザー名かユーザーIDからユーザーを検索する
Follows lookupユーザーIDからフォローしてる・されてる人を取得する
Manage followsユーザーIDからフォロー・フォロー解除を行う

公式から引っ張ってきただけ。
https://developer.twitter.com/en/docs/twitter-api/early-access

1. 実験

Twitter API v2を使用して任意のユーザーアカウントの情報に加えて、フォロワーのユーザー情報を取得する。

ソースコードは後述する。
またTwitter API自体の使い方については以下の記事に書いてある。

  • 実験対象

自分のTwitterアカウントで実験する。



1.1. User lookup

User lookupの機能を使うとユーザー名かユーザーIDからユーザーを検索して、その情報を取得できる。
勘違いしやすいがTwitterには名前(name)とユーザー名(username)の両方が存在する。
@の後に続くものをユーザー名と呼ぶ。

ユーザーID(id)に関してはプロフィール上には表示されず変更もできない。



User lookupにより取得できるユーザー情報について、
このアカウントのユーザー名「@CircleKENdotNet」から得た情報を例として以下の表により説明する。

種類説明
idstringユーザーのID4790312834
namestringユーザーの名前KEN
usernamestringユーザーの名前(@の後のやつ)CircleKENdotNet
created atdate (ISO 8601)アカウント作成時刻2016-01-20T 20:43:52.000Z
protectedboolean鍵アカウントかどうかFALSE
withheldobject地域の法律により表示が差し控えられているプロフィールの詳細
locationstring地域
urlstringurlURL省略
descriptionstring自己紹介欄(bioとも呼ばれる)「プリティーシリーズ」の新アニメ「キラッとプリ☆チャン」 4月8日より毎週(日)ごぜん10:00~テレビ東京系6局ネット、 毎週(火)ゆうがた17:29~BSジャパンにて放送!
verifiedboolean公式アカウントかどうかFALSE
entitiesobject埋め込まれているurlの情報{‘url’: {‘urls’: [{‘start’: 0, ‘end’: 23, ‘url’: ‘URL省略’, ‘expanded_url’: ‘URL省略’, ‘display_url’: ‘URL省略’}]}}
profilel image urlstringプロフィール画像URL省略
public metricsobjectフォロー数、フォロワー数、ツイート数、リストに入っている数{‘followers count’: 780, ‘following_count’: 0, ‘tweet_count’: 41, ‘listed_count’: 7}
pinned tweet idstring固定ツイートのツイートID


「location」は住んでる場所を登録してないので空欄。
プロフィール上に表示される情報以外にも「id」や「listed_count(リストに入れられている数)」など普段見えない数字も見える。
なぜかヘッダー画像は取得できない。

1.2. Follows lookup

Follows lookupの機能を使うとユーザーIDからユーザーを検索して、そのユーザーのフォローしてる人かされてる人のユーザー情報を取得できる。
取得できるユーザー情報はさっきのUser lookupにより取得できる情報と同じ。

ユーザーIDが分かればいいので、別に自分のアカウントでなくとも任意のアカウントのフォロワーの情報が取得できる。

これによって780人のフォロワー分の情報が取得できた。

2. コード

Twitter API v2によりユーザー情報を取得してCSVファイルに保存するコード。

2.1. User lookup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import requests
import os
import csv

##### FUNCTIONS
# usernames:ユーザー名 user_fields:取得データ APIリクエスト用のURLを作成
def create_url(usernames, user_fields):
if(any(usernames)):
formatted_user_names = "usernames=" + ",".join(usernames)
else:
formatted_user_names = ""

if(any(user_fields)):
formatted_user_fields = "user.fields=" + ",".join(user_fields)
else:
formatted_user_fields = "user.fields=id,name,username"

url = "https://api.twitter.com/2/users/by?{}&{}".format(formatted_user_names, formatted_user_fields)
return url


# bearer_token:APIキー APIリクエスト用のヘッダーを作成
def create_headers(bearer_token):
headers = {"Authorization": "Bearer {}".format(bearer_token)}
return headers

# url:APIリクエスト用のURL headers:APIリクエスト用のヘッダー APIリクエスト
def connect_to_endpoint(url, headers):
response = requests.request("GET", url, headers=headers)
print(response.status_code)
if response.status_code != 200: # HTTPレスポンスステータスコードが200以外ならエラー
raise Exception("Request returned an error: {} {}".format(response.status_code, response.text))
return response.json()

# filename:出力ファイル名 header:ヘッダー contents_list:中身
def save_csvfile(filename, header, contents_list):
if(not os.path.isfile(filename)): # 既存の同名ファイルがなければ新規作成
with open(filename, "w", newline="", encoding="utf-16") as f:
w = csv.DictWriter(f, fieldnames=header, dialect="excel-tab", quoting=csv.QUOTE_ALL)
w.writeheader()

with open(filename, "a", newline="", encoding="utf-16") as f:
w = csv.DictWriter(f, fieldnames=header, dialect="excel-tab", quoting=csv.QUOTE_ALL)
for contents in contents_list:
for k in contents.keys(): #### 文字列内のNullを除去
if(type(contents[k]) is str): contents[k] = contents[k].replace("\0", "")
w.writerow(contents)

#### MAIN
def main():
#### VARIABLES
# APIキー https://developer.twitter.com から取得
BEARER_TOKEN = r"取得したBEARER_TOKEN"
# ユーザー名 Twitterアカウントの @の後のやつ
usernames = ["CIrcleKENdotNet",]
# 取得データ e.g. user_fields = ["id", "name", "username", "created_at", "description"]
# created_at(作成時刻), description(アカウントの自己紹介)などの情報が欲しい場合はtweet_fieldsに書く
user_fields = ["id", "name", "username", "created_at","protected",
"withheld", "location", "url", "description", "verified", "entities",
"profile_image_url", "public_metrics", "pinned_tweet_id"]
# 保存するCSVファイルの名前
save_csv_filename = "twitter_user_info.csv"

#### データ取得
url = create_url(usernames, user_fields)
headers = create_headers(BEARER_TOKEN)
json_response = connect_to_endpoint(url, headers)
data = json_response["data"]

#### 取得データ保存
save_csvfile(save_csv_filename, user_fields, data)


if __name__ == "__main__":
main()

2.2. Follows lookup

フォロー、フォロワーの取得は1リクエストにつき最大1000件までしか返ってこないのでnext_tokenというものを受け取って続きから再リクエストする必要がある。
以下のコードはその辺も組み込んで一度に1001以上のユーザー情報を取得できるようにしてある。

15分あたり300リクエストまで許されるので30万件までなら一度に取得できる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import requests
import os
import csv
import re

##### FUNCTIONS
# usernames:ユーザー名 user_fields:取得データ APIリクエスト用のURLを作成
def create_url(user_id, ff, max_results, next_token, user_fields):
if(any(user_fields)):
formatted_user_fields = "user.fields=" + ",".join(user_fields)
else:
formatted_user_fields = ""
if(next_token is not None):
formatted_next_token = "&pagination_token=" + (next_token)
else:
formatted_next_token = ""
if(max_results > 1000): max_results = 1000
#&pagination_token=
url = "https://api.twitter.com/2/users/{}/{}?max_results={}{}&{}".format(user_id, ff, max_results, formatted_next_token, formatted_user_fields)
return url


def create_headers(bearer_token):
headers = {"Authorization": "Bearer {}".format(bearer_token)}
return headers


def connect_to_endpoint(url, headers):
response = requests.request("GET", url, headers=headers)
print(response.status_code)
if response.status_code != 200:
raise Exception("Request returned an error: {} {}".format(response.status_code, response.text))
return response.json()

# filename:出力ファイル名 header:ヘッダー contents_list:中身
def save_csvfile(filename, header, contents_list):
if(not os.path.isfile(filename)): # 既存の同名ファイルがなければ新規作成
with open(filename, "w", newline="", encoding="utf-16") as f:
w = csv.DictWriter(f, fieldnames=header, dialect="excel-tab", quoting=csv.QUOTE_ALL)
w.writeheader()

with open(filename, "a", newline="", encoding="utf-16") as f:
w = csv.DictWriter(f, fieldnames=header, dialect="excel-tab", quoting=csv.QUOTE_ALL)
for contents in contents_list:
for k in contents.keys(): #### 文字列内のNullを除去
if(type(contents[k]) is str): contents[k] = contents[k].replace("\0", "")
w.writerow(contents)

#### MAIN
def main():
#### VARIABLES
# APIキー https://developer.twitter.com から取得
BEARER_TOKEN = r"取得したBEARER_TOKEN"
# ユーザーID
user_id = 4790312834
# フォローしてる人を探すときは[0] フォロワーを探すときは[1]
ff = ["following", "followers"][1]
# 取得したいデータ数
max_results = 10000

# 取得データ e.g. user_fields = ["id", "name", "username", "created_at", "description"]
# created_at(作成時刻), description(アカウントの自己紹介)などの情報が欲しい場合はtweet_fieldsに書く
user_fields = ["id", "name", "username", "created_at","protected",
"withheld", "location", "url", "description", "verified", "entities",
"profile_image_url", "public_metrics", "pinned_tweet_id"]

#### データ取得
next_token = None
data_len = 0
while(True):
url = create_url(user_id, ff, max_results, next_token, user_fields)
headers = create_headers(BEARER_TOKEN)
json_response = connect_to_endpoint(url, headers)
data = json_response["data"]
meta = json_response["meta"]

#### 取得データ保存(user_id + [following or followers] + .csv)
csv_file_name = re.sub(r'[\\/:*?"<>|.]+','',str(user_id) + "_" + ff ) + ".csv" # ファイルに使えない文字削除
save_csvfile(csv_file_name, user_fields, data)

#### 終了チェック(欲しい数に達するか全て取り終わったら終了)
data_len += len(data)
if(max_results <= data_len): break
if(not "next_token" in meta): break
next_token = meta["next_token"]
pass

if __name__ == "__main__":
main()

3. Twitter API リンク

タグ ,

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×