ひゃまだのblog

ひゃまだ(id:hymd3a)の趣味のブログ

pythonでtwitterの投稿に「いいね」してくれたユーザの一覧(API Ver2)を出力する

(2021-06-10 初稿 - )

はじめに

TwitterAPI Ver2が公開されて、投稿に「いいね」(like)してくれた人の一覧を得ることができるようになった。ただし、1 tweetあたり100個までとのこと。筆者の場合は、超余裕の仕様。(笑)

せっかくなので、API Ver2で自分の投稿に「いいね」してくれた奇特な方の一覧を取得してみた。

ちなみに、筆者の環境は以下のとおり。

検索の仕方が悪く、良いサイトが見つからなかったので、変なスクリプトを自作。^^;

スクリプト自体は、上記サイトの主にcurlの部分を参考に作成した。

f:id:hymd3a:20210610175911p:plain

Twitter画面

準備

スクリプトの作成よりも、準備の方が数倍大変。(-_-;)

アプリケーションの登録と各種tokenキーなどの取得

以下のdeveloperのサイトにログインして、なんとかしてアプケーションを登録。

その際、V1.1 ACCESSとV2 ACCESSができるようにプロジェクトを作成し、スタンドアロンにはしないこと。なお、登録等の詳細は他のサイトを検索してね(手抜き)

必要なキーは、consumer_key、consumer_secret、access_token_key、access_token_secretとbearer_tokenで、全てメモをしておくこと。

ただし、このページのスクリプトでは、bearer_tokenしか使わない

ユーザーIDの確認

スクリプトでは、user_idが必要になる。普段見る機会が少ないが、以下のサイト等を参照して、自分のuser_idを確認する。

要約すると、Twitterのホームページをブラウザで開き、ソースコードを表示して、「user_id」を検索する。

スクリプトの作成

Bearer_tokenとuser_idを手元に準備できたら、スクリプトを作成を開始する。

なお、筆者は、pythonも素人なので、いろいろ指摘してね。

自分の直近のtweet idを取得する

「いいね」してくれたユーザ一覧を取得するためには、まずtweet idを取得する必要がある。

tweet idも普段見ないが、自分のtweet一つだけをブラウザで開いてみると、アドレスバーに並んでいる数字列がtweet id。

さて、tweet id取得の参考になるのは、上記サイトの以下のcurlスクリプト

curl -H "Authorization: Bearer $BEARER_TOKEN" "https://api.twitter.com/2/users/{use_id}/tweets?max_results=5"

ヘッダーにbearer_tokenを指定、user_idを記入して、twitterapiにアクセスすれば良いよう…

curlが使える環境ならば、自分のtweetが5件取得できるか実際に試してみて。

この部分を、pythonにすると以下のよう。

url = "https://api.twitter.com/2/users/{}/tweets?max_results={}".format(user_id,MAX_COUNT)
head = {"Authorization": "Bearer {}".format(bearer_token)}
req = urllib.request.Request(url, headers=head)
res = urllib.request.urlopen(req).read()

ちなみに、MAX_COUNTは最大100個までだそうだが、あまりに多いのは負荷がかかるのでやめようね。

{
  "data": [
    {
      "id": "1338971066773905408",
      "text": "💡 Using Twitter data for academic research? Join our next livestream this Friday @ 9am PT on https://t.co/GrtBOXh5Y1!n n@SuhemParack will show how to get started with recent search & filtered stream endpoints on the #TwitterAPI v2, the new Tweet payload, annotations, & more. https://t.co/IraD2Z7wEg"
    },
    (中略)
    {
      "id": "1334564488884862976",
      "text": "Before we release new #TwitterAPI endpoints, we let developers test drive a prototype of our intended design. @i_am_daniele takes you behind the scenes of an endpoint in the making. https://t.co/NNTDnciwNq"
    }
  ],
  "meta": {
    "oldest_id": "1334564488884862976",
    "newest_id": "1338971066773905408",
    "result_count": 5,
    "next_token": "7140dibdnow9c7btw3w29grvxfcgvpb9n9coehpk7xz5i"
  }
}

取得データは、jsonの形式で、'meta'の'result_count'が5であることに注目。

返ってきたjsonを辞書型にコンバートすると配列のように扱えてとても便利。

td_dic = json.loads(res.decode('utf-8'))

例えば、最初のtweet_idとresult_countを表示するには、以下のとおり。

print(tid_dic['data'][0]['id'])          #  1338971066773905408
print(tid_dic['meta']['result_count'])   # 5

Tweet IDごとの「いいね」(liking_users)の一覧を取得

Tweet idが取得できるようになったので、各tweet idごとのいいねユーザ(liking_users)の一覧を取得する。

curl -H "Authorization: Bearer $BEARER_TOKEN" https://api.twitter.com/2/tweets/{tweet_id}/liking_users

上記をpythonにすると以下のとおり。

url = "https://api.twitter.com/2/tweets/{}/liking_users".format(str(post_id))
head = {"Authorization": "Bearer {}".format(bearer_token)}
req = urllib.request.Request(url, headers=head)
res = urllib.request.urlopen(req).read()

やはり、これも辞書型に変換して、以下のとおりダラダラと出力。

for i in range(uids['meta']['result_count']):
    print(uids['data'][i]['id'], uids['data'][i]['name'], uids['data'][i]['username'])

作成したスクリプトの実行

作成したスクリプトの全体は、以下のとおり(p-tw-likes.py)。

#!/usr/bin/env python3
#coding: UTF-8

import json
import time
import urllib.request
import urllib.parse
import urllib.error

#  Constant
NAME = 'hymd3a'
USERID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'        # たくさんの数字列
MAX_COUNT = 5

def getMyTweetId(user_id):
    try:
        url = "https://api.twitter.com/2/users/{}/tweets?max_results={}".format(user_id,MAX_COUNT)
        head = {"Authorization": "Bearer {}".format(bearer_token)}
        req = urllib.request.Request(url, headers=head)
        res = urllib.request.urlopen(req).read()
        td = json.loads(res.decode('utf-8'))
        #print(json.dumps(td, indent=4, sort_keys=True, ensure_ascii=False))
        return td
    except urllib.error.HTTPError as err:
        print(err.reason, err.code)
        return False

def getUserIDsPostLikes(post_id):
    time.sleep(1)
    try:
        url = "https://api.twitter.com/2/tweets/{}/liking_users".format(str(post_id))
        head = {"Authorization": "Bearer {}".format(bearer_token)}
        req = urllib.request.Request(url, headers=head)
        res = urllib.request.urlopen(req).read()
        jd = json.loads(res.decode('utf-8'))
        #print(json.dumps(jd, indent=4, sort_keys=True, ensure_ascii=False))
        return jd
    except urllib.error.HTTPError as err:
        print(err.reason, err.code)
        return False

# Bearer Token
bearer_token="xxxxxxTakusanxnoxMojixgaxNarandexIruyoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

tid_dic = getMyTweetId(USERID)

for i in range(tid_dic['meta']['result_count']):
    uids = getUserIDsPostLikes(tid_dic['data'][i]['id'])
    for i in range(uids['meta']['result_count']):
        print(uids['data'][i]['id'], uids['data'][i]['name'], uids['data'][i]['username'])

実行は、以下のようにすると、たくさんいいねしてくれたユーザがわかり、感謝しないとね。

./p-tw-likes.py | sort | uniq -c | sort -n
      User ID           Name     Username  
  1 917984000000000000 ユーザ1    lemon
  2 000000000000092305 ユーザ2    orange
  2 935800000000000231 ユーザ3    apple
  3 000000000087439106 ユーザ4    pine
  4 891467010000000000 ユーザ5    grape

sort、特にuniq -cがカウントしてくれて、とてもいい働きをしてくれて感謝。