見出し画像

【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を一括で取得したい)の実現には十分だった。

いいなと思ったら応援しよう!