Twitter(X)でいいねしたものを全て取得するスクリプト
3 min read
こんにちは、無能です。Twikitという非公式APIでTwitterのスクレイピングをできる訳なのですが、ちょっと前からサンプルコードに非同期を推奨するようなことがありアップグレードして気づいたら非同期でやりなさいと怒られるようになったので全て修正しました。
haturatu/xd_likes
こんな感じで最初に all_tweets
に格納していきます。
指定した最大値をgetしたら
all_tweets
のツイートのツイート内容を全て取得していきます。
これは全て fav.log
に書き出しがされていく為、必要になった場合grepで全て情報を引き出せます。
API制限
https://github.com/d60/twikit/blob/main/ratelimits.md
この通り、API制限に関してそれぞれ結構違います。
なのでリトライ設定で何度か試行してあげる必要がありました。
# リトライ設定
RETRY_LIMIT = 10
RETRY_DELAY = 300
# リトライ時に実行させる関数
async def perform_request_with_retries(request_func, *args, **kwargs):
for attempt in range(RETRY_LIMIT):
try:
response = await request_func(*args, **kwargs) # 非同期リクエストを待機
if response:
return response
except ReadTimeout:
logger.warning(f"Attempt {attempt + 1} failed due to ReadTimeout.")
except Exception as e:
logger.error(f"Attempt {attempt + 1} failed: {e}")
await asyncio.sleep(RETRY_DELAY)
raise Exception("Failed to fetch more tweets after retries.")
API制限は15分でリセットされるらしいので、合計50分試行できるのであれば十分に時間の猶予を作れたかなと思います。何気にここが結構詰まった部分で、ギリギリを攻めていったら無限に時間が食われたので思いっきり最大値を引き上げました。
画像保存
いいねを取得するものと別にダウンロードをするスクリプトを別けています。
xd.py
にて画像保存をしていきます。
標準のままであると、最高画質で保存出来ないので取得したURLに対してorignalのパラメータを付与してあげます。
while user_tweets:
for tweet in user_tweets:
for media in tweet.media:
url = media['media_url_https']
if url.endswith('.jpg'):
url = url.replace('.jpg', '?format=jpg&name=orig')
clean_url = get_clean_url(url)
save_path = os.path.join(save_folder, f"{screen_name}_{clean_url.split('/')[-1]}.jpeg")
await download_image(url, save_path)
pngのほうが画質はきれいなのですが、おそらくpngであげられているものしか存在しない?パラメータかつpngが結構容量食うのでjpgで妥協しました。
取得するID別にフォルダを作ってそこに保存していき、一応画像側にもIDを付与するという日本人も嬉しい丁寧仕様です。
現状では他に同じようなスクリプト見当たらなかったので公開してみました。というかみんなこっそりやる系だからあんま公開しようとしないんでしょうが・・・。
ちなみに、fav.logでいいねしたURLがあるのでいいねした投稿だけ画像保存したいのであれば、また別で行う必要がありますが一応できます。そのためにfav.logに全て入れるようにしています。
実際、fav.logとツイート全件fetchしたときのログは別に別けたほうがいいかなあと思いましたがもう疲れたのでここで終わりとします。
それでは。
またよろしくお願いします。