Twitter 上でこちらのことをフォローしてくれた方を
自動的にフォロー返しするツールを作成することがありました。
Twitter API を用いて実装したため、特に難しいことはなかったのですが、
一応備忘録に残しておきます。
サンプルコードも載せておきますので、良かったら参考にしてみてください。
環境は Windows10、Python3 です。
Twitter API を使用する事前準備
Twitter API を使用するための準備を行います。
(Python はインストール済みであることを前提とします)
APIキーとアクセストークンの発行
Twitter API を使用するためには、APIキーとアクセストークンの発行が必要です。
まだ発行していない場合は、以下の記事を参考にしてこれらを発行してください。
発行は1時間程度で終わります。
requests_oauthlib モジュールのインストール
以下で紹介するサンプルコードを実行するにあたり、
requests_oauthlib モジュールが必要ですので、以下コマンドでインストールしておきます。
1 2 3 |
pip install requests_oauthlib |
インストール時の実行ログ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
> pip install requests_oauthlib Collecting requests_oauthlib Downloading requests_oauthlib-1.3.0-py2.py3-none-any.whl (23 kB) Requirement already satisfied: requests>=2.0.0 in c:\users\xxxxxxxxx\appdata\local\programs\python\python37\lib\site-packages (from requests_oauthlib) (2.21.0) Collecting oauthlib>=3.0.0 Downloading oauthlib-3.1.0-py2.py3-none-any.whl (147 kB) |■■■■■■■■■■■■■■■■| 147 kB 819 kB/s Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\users\xxxxxxxxx\appdata\local\programs\python\python37\lib\site-packages (from requests>=2.0.0->requests_oauthlib) (3.0.4) Requirement already satisfied: urllib3<1.25,>=1.21.1 in c:\users\xxxxxxxxx\appdata\local\programs\python\python37\lib\site-packages (from requests>=2.0.0->requests_oauthlib) (1.24.1) >requests_oauthlib) (2018.11.29) Installing collected packages: oauthlib, requests-oauthlib Successfully installed oauthlib-3.1.0 requests-oauthlib-1.3.0 |
|
|
Twitter API で特定のユーザーをフォローするサンプルコード
以下、Twitter 上で特定のユーザーをフォローするサンプルコードです。
引数として、フォローしたい相手のユーザーIDを指定しています。
また、事前準備で取得した 4 つのキーもそれぞれ渡しています。
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 |
# 必要なモジュールのインポート from requests_oauthlib import OAuth1Session import json # 引数で与えた USER_ID のユーザーをフォローする def post_twitter_follower_follow(user_id, consumer_key, consumer_secret, access_token, access_token_secret): # 認証情報を設定 twitter = OAuth1Session(consumer_key, consumer_secret, access_token, access_token_secret) # ユーザーフォローのエンドポイントを設定 url = "https://api.twitter.com/1.1/friendships/create.json" # フォローするユーザーの USER_ID を設定 params = {"user_id" : user_id} # POST の実行 response = twitter.post(url, params = params) data = response.json() # レスポンスを Python 辞書形式へ変換 # 結果の取得 ## 正常終了 if response.status_code == 200: print(json.dumps(data, indent=4)) # レスポンスを表示 ## 異常終了 else: print("failed!") print(data) if __name__ == '__main__': user_id = xxxxxx post_twitter_follower_follow(user_id, "【consumer_key を入力】", "【consumer_secret を入力】", "【access_token を入力】", "【access_token_secret を入力】") |
Twitter 開発者 ドキュメント日本語訳 POST friendships/create
上記のドキュメントに記載がありますが、
指定するのはユーザーIDではなく、フォロー対象ユーザーのユーザー名でもOKです。
その場合、上記サンプルコードで user_id を渡しているところで、
代わりに screen_name (String) で渡してやればよいです。
ツイート投稿のレスポンス一覧
上記コードでユーザーフォローした際、返却されるレスポンスの例を以下に記載します。
※個人を特定できそうな個所は伏字に置換しています。
サンプルコード内でも実施していますが、json 形式で受け取ることで、
レスポンスから情報を引き抜くことができます。
たとえば、フォロー相手のフォロワー数を取得したい場合は、data[“followers_count”] 、
フォロワー相手がフォローしている数を取得したい場合は、data[“friends_count”] と
それぞれ記載すれば OK です。
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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
{ "id": xxxxxxxxxxxxxxxxxxx, "id_str": "xxxxxxxxxxxxxxxxxxx", "name": "【フォロー相手の名前】", "screen_name": "senanpa01", "location": "", "description": "【フォロー相手の自己紹介文】", "url": null, "entities": { "description": { "urls": [] } }, "protected": false, "followers_count": xxx【フォロー相手のフォロワー数】, "friends_count": xxx【フォロー相手がフォローしている数】, "listed_count": 0, "created_at": "Mon Dec 18 23:43:46 +0000 2017", "favourites_count": xxx【フォロー相手の"いいね"した数】, "utc_offset": null, "time_zone": null, "geo_enabled": false, "verified": false, "statuses_count": 116, "lang": null, ★ここから下の "status" 項目は、フォロワー対象ユーザーがツイートやリツイートした内容です★ "status": { "created_at": "Wed Apr 22 15:29:05 +0000 2020", "id": XXXXXXXXXXXXXX【リツイート対象ユーザーID】, "id_str": "XXXXXXXXXXXXXX【リツイート対象ユーザーID】", "text": "【リツイート内容】", "truncated": false, "entities": { "hashtags": [], "symbols": [], "user_mentions": [ { "screen_name": "XXXXXXXXXX", "name": "YYYYYYYY", "id": xxxxxxxxxx, "id_str": "xxxxxxxxxx", "indices": [ 3, 14 ] } ], "urls": [], "media": [ { "id": zzzzzzzzzzzzzzzzzzz, "id_str": "zzzzzzzzzzzzzzzzzzz", "indices": [ 30, 53 ], "media_url": "http://pbs.twimg.com/media/xxxxxxxxxx.jpg", "media_url_https": "https://pbs.twimg.com/media/xxxxxxxxxx.jpg", "url": "https://t.co/XXXXXXXXXX", "display_url": "pic.twitter.com/xxxxxxxxxx", "expanded_url": "https://twitter.com/XXXXXXXXXX/status/zzzzzzzzzzzzzzzzzzz/photo/1", "type": "photo", "sizes": { "small": { "w": 441, "h": 680, "resize": "fit" }, "thumb": { "w": 150, "h": 150, "resize": "crop" }, "large": { "w": 673, "h": 1037, "resize": "fit" }, "medium": { "w": 673, "h": 1037, "resize": "fit" } }, "source_status_id": zzzzzzzzzzzzzzzzzzz, "source_status_id_str": "zzzzzzzzzzzzzzzzzzz", "source_user_id": xxxxxxxxxx, "source_user_id_str": "xxxxxxxxxx" } ] }, "extended_entities": { "media": [ { "id": zzzzzzzzzzzzzzzzzzz, "id_str": "zzzzzzzzzzzzzzzzzzz", "indices": [ 30, 53 ], "media_url": "http://pbs.twimg.com/media/xxxxxxxxxx.jpg", "media_url_https": "https://pbs.twimg.com/media/xxxxxxxxxx.jpg", "url": "https://t.co/XXXXXXXXXX", "display_url": "pic.twitter.com/XXXXXXXXXX", "expanded_url": "https://twitter.com/XXXXXXXXXX/status/zzzzzzzzzzzzzzzzzzz/photo/1", "type": "photo", "sizes": { "small": { "w": 441, "h": 680, "resize": "fit" }, "thumb": { "w": 150, "h": 150, "resize": "crop" }, "large": { "w": 673, "h": 1037, "resize": "fit" }, "medium": { "w": 673, "h": 1037, "resize": "fit" } }, "source_status_id": zzzzzzzzzzzzzzzzzzz, "source_status_id_str": "zzzzzzzzzzzzzzzzzzz", "source_user_id": xxxxxxxxxx, "source_user_id_str": "xxxxxxxxxx" }, { "id": nnnnnnnnnnnnnnnnnnn, "id_str": "nnnnnnnnnnnnnnnnnnn", "indices": [ 30, 53 ], "media_url": "http://pbs.twimg.com/media/ZZZZZZZZZZZZZZZ.jpg", "media_url_https": "https://pbs.twimg.com/media/ZZZZZZZZZZZZZZZ.jpg", "url": "https://t.co/XXXXXXXXXX", "display_url": "pic.twitter.com/XXXXXXXXXX", "expanded_url": "https://twitter.com/XXXXXXXXXX/status/zzzzzzzzzzzzzzzzzzz/photo/1", "type": "photo", "sizes": { "small": { "w": 452, "h": 680, "resize": "fit" }, "thumb": { "w": 150, "h": 150, "resize": "crop" }, "medium": { "w": 684, "h": 1030, "resize": "fit" }, "large": { "w": 684, "h": 1030, "resize": "fit" } }, "source_status_id": zzzzzzzzzzzzzzzzzzz, "source_status_id_str": "zzzzzzzzzzzzzzzzzzz", "source_user_id": xxxxxxxxxx, "source_user_id_str": "xxxxxxxxxx" } ] }, "source": "<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone</a>", "in_reply_to_status_id": null, "in_reply_to_status_id_str": null, "in_reply_to_user_id": null, "in_reply_to_user_id_str": null, "in_reply_to_screen_name": null, "geo": null, "coordinates": null, "place": null, "contributors": null, "retweeted_status": { "created_at": "Wed Apr 22 02:07:28 +0000 2020", "id": zzzzzzzzzzzzzzzzzzz, "id_str": "zzzzzzzzzzzzzzzzzzz", "text": "【ツイート文章】 https://t.co/XXXXXXXXXX", "truncated": false, "entities": { "hashtags": [], "symbols": [], "user_mentions": [], "urls": [], "media": [ { "id": zzzzzzzzzzzzzzzzzzz, "id_str": "zzzzzzzzzzzzzzzzzzz", "indices": [ 14, 37 ], "media_url": "http://pbs.twimg.com/media/xxxxxxxxxx.jpg", "media_url_https": "https://pbs.twimg.com/media/xxxxxxxxxx.jpg", "url": "https://t.co/XXXXXXXXXX", "display_url": "pic.twitter.com/XXXXXXXXXX", "expanded_url": "https://twitter.com/XXXXXXXXXX/status/zzzzzzzzzzzzzzzzzzz/photo/1", "type": "photo", "sizes": { "small": { "w": 441, "h": 680, "resize": "fit" }, "thumb": { "w": 150, "h": 150, "resize": "crop" }, "large": { "w": 673, "h": 1037, "resize": "fit" }, "medium": { "w": 673, "h": 1037, "resize": "fit" } } } ] }, "extended_entities": { "media": [ { "id": zzzzzzzzzzzzzzzzzzz, "id_str": "zzzzzzzzzzzzzzzzzzz", "indices": [ 14, 37 ], "media_url": "http://pbs.twimg.com/media/xxxxxxxxxx.jpg", "media_url_https": "https://pbs.twimg.com/media/xxxxxxxxxx.jpg", "url": "https://t.co/XXXXXXXXXX", "display_url": "pic.twitter.com/XXXXXXXXXX", "expanded_url": "https://twitter.com/XXXXXXXXXX/status/zzzzzzzzzzzzzzzzzzz/photo/1", "type": "photo", "sizes": { "small": { "w": 441, "h": 680, "resize": "fit" }, "thumb": { "w": 150, "h": 150, "resize": "crop" }, "large": { "w": 673, "h": 1037, "resize": "fit" }, "medium": { "w": 673, "h": 1037, "resize": "fit" } } }, { "id": nnnnnnnnnnnnnnnnnnn, "id_str": "nnnnnnnnnnnnnnnnnnn", "indices": [ 14, 37 ], "media_url": "http://pbs.twimg.com/media/ZZZZZZZZZZZZZZZ.jpg", "media_url_https": "https://pbs.twimg.com/media/ZZZZZZZZZZZZZZZ.jpg", "url": "https://t.co/XXXXXXXXXX", "display_url": "pic.twitter.com/XXXXXXXXXX", "expanded_url": "https://twitter.com/XXXXXXXXXX/status/zzzzzzzzzzzzzzzzzzz/photo/1", "type": "photo", "sizes": { "small": { "w": 452, "h": 680, "resize": "fit" }, "thumb": { "w": 150, "h": 150, "resize": "crop" }, "medium": { "w": 684, "h": 1030, "resize": "fit" }, "large": { "w": 684, "h": 1030, "resize": "fit" } } } ] }, "source": "<a href=\"https://www.xxxxxx.net/\" rel=\"nofollow\">MateCha</a>", "in_reply_to_status_id": null, "in_reply_to_status_id_str": null, "in_reply_to_user_id": null, "in_reply_to_user_id_str": null, "in_reply_to_screen_name": null, "geo": null, "coordinates": null, "place": null, "contributors": null, "is_quote_status": false, "retweet_count": 14209, "favorite_count": 29477, "favorited": false, "retweeted": false, "possibly_sensitive": false, "lang": "ja" }, "is_quote_status": false, "retweet_count": 14209, "favorite_count": 0, "favorited": false, "retweeted": false, "possibly_sensitive": false, "lang": "ja" }, ★フォロワー対象ユーザーがツイートやリツイートした内容 ここまで★ "contributors_enabled": false, "is_translator": false, "is_translation_enabled": false, "profile_background_color": "F5F8FA", "profile_background_image_url": null, "profile_background_image_url_https": null, "profile_background_tile": false, "profile_image_url": "http://pbs.twimg.com/profile_images/XXXXXXXXXXXXXXXXXXX/ZZZZZZZZZZZZZZZ.jpg", "profile_image_url_https": "https://pbs.twimg.com/profile_images/XXXXXXXXXXXXXXXXXXX/ZZZZZZZZZZZZZZZ.jpg", "profile_link_color": "1DA1F2", "profile_sidebar_border_color": "C0DEED", "profile_sidebar_fill_color": "DDEEF6", "profile_text_color": "333333", "profile_use_background_image": true, "has_extended_profile": false, "default_profile": true, "default_profile_image": false, "following": false, "follow_request_sent": false, "notifications": false, "muting": false, "translator_type": "none" } |
1つ気になる箇所としては、
“following” の項目は、こちらが相手をフォローしている場合は “true” になりますが、
上記サンプルコードでフォローした際に返されるレスポンスでは、”false” になっていました。
フォローした相手の情報を正常に取得する場合は、以下ページで紹介している
サンプルコードを参考に、フォロワーの状態情報を取得したするのが良いと思います。
(Twitter API の前準備の部分はスキップしてください)
以上、参考になれば幸いです^^
コメント