本文へスキップ

API による Twitter プロフィールの一括取得

Twitter のプロフィールを一括で取得するには、ユーザー名またはユーザー ID を100件ずつバッチ取得エンドポイントに送ります。1万アカウントなら100リクエストで、各アカウントのフォロワー数、自己紹介、登録日が返ります。

結論: 公式 X API のユーザー取得は、1回の呼び出しでユーザー名または ID を100件受け付け、1プロフィールあたり$0.010で課金されます。そのため1万プロフィールで$100、1つのアプリが処理できるのは1時間あたり最大12万件です。Sorsa API の GET /info-batch なら、同じ100プロフィールを1リクエストで、1,000件あたり$0.014から取得できます。100回分の無料リクエストで、最初の10,000件を取得できます。

エンドポイント
GET /info-batch
1ページの件数
1リクエストあたり100プロフィール
料金
1,000件あたり$0.014から

#Twitter プロフィール一括取得の仕組み

プロフィールの一括取得では、アカウントのリストを1回のリクエストで送り、存在するアカウントごとに1件のプロフィールレコードが返ります。リストにはユーザー名か数値のユーザー ID のどちらかを、1回の呼び出しで最大100件入れられます。どのレコードにも同じフィールドが入っています。アカウントの ID、表示名、自己紹介、所在地、登録日、フォロワー数とフォロー数、投稿数、認証フラグです。

1、2件のアカウントなら、コードは不要です。Twitter アカウント比較なら、2つのプロフィールを無料で並べて見られます。数百から数百万のアカウントのリストには API が必要です。やることはどこでも同じで、リストを100件ずつに分け、チャンクごとにバッチエンドポイントを1回呼び出し、結果の行をファイルかデータベースに書き込みます。

公式 X API では、これらのエンドポイントをユーザー取得(user lookup)(新しいタブで開きます)と呼びます。GET /2/users はユーザー ID を最大100件、GET /2/users/by はユーザー名を最大100件受け付けます。ID、名前、ユーザー名以外のフィールドは user.fields で指定する必要があります。X の料金ページ(新しいタブで開きます)では、User: Read は返されたプロフィール1件あたり$0.010(1,000件あたり$10.00)で、同じアカウントはUTC の1日につき1回だけ課金されます。呼び出しには開発者アカウントとベアラートークンが必要で、レート制限(新しいタブで開きます)はアプリあたり15分に300リクエストです。つまり15分あたり最大3万プロフィールです。

存在しなくなったアカウントはエラーになりません。入力ミスのユーザー名、名前が変わったアカウント、凍結または削除されたアカウントは、レスポンスにレコードがないだけです。そのため、取得処理では必ず、返ってきた結果を送ったリストと突き合わせます。

リスト 分割 チャンクごとに1回呼び出し 2つのファイル accounts.csv 2.5万アカウント harborline_analytics @quietfield_records 1612371430079911386 名前、リンク、ID 250チャンク 各100件 100 100 100 GET /info-batch 250リクエスト 毎秒20件 約13秒 キー1つで profiles.csv アカウントごとに1行 各19フィールド missing.csv プロフィールなし 改名または削除
処理全体は、100アカウントにつき1リクエストです。返ってこなかったものは別のファイルに入るので、黙って消えることはありません。

#Sorsa API でプロフィールを一括取得する

公開データ向けの Twitter(X)API 兼スクレイピングツール である Sorsa API は、1つのエンドポイントで取得処理のすべてをこなします。GET /info-batch(新しいタブで開きます) は1リクエストでユーザー名または ユーザー ID を最大100件受け付け、すべてのフィールドを含むプロフィールを返します。切り替える設定は不要です。何千もの X プロフィールを一度に取得するなら、Sorsa API を使ってください。1リクエストで100プロフィール、全プランで毎秒20リクエスト、1,000プロフィールあたり$0.014からです。

  1. キーを取得する。 サインアップして、ダッシュボードから API キーをコピーします。アカウントには100回分の無料リクエストが付き、カードは不要です。Sorsa API が X のログイン情報を求めることはありません。

  2. 最大100件のユーザー名を送る。 usernames パラメータを、アカウントごとに1回ずつ、@ を付けずに繰り返します。

    ターミナル
    curl -G "https://api.sorsa.io/v3/info-batch" \
      -H "ApiKey: YOUR_API_KEY" \
      --data-urlencode "usernames=harborline_analytics" \
      --data-urlencode "usernames=quietfield_records" \
      --data-urlencode "usernames=deleted_account_2019"
    
    レスポンス200 OK
    {
      "users": [
        {
          "id": "1427632236659332516",
          "username": "harborline_analytics",
          "display_name": "Harborline Analytics",
          "description": "Port and shipping data, charted weekly.",
          "location": "Rotterdam",
          "created_at": "2021-08-17T14:03:44Z",
          "followers_count": 3912,
          "followings_count": 418,
          "tweets_count": 2276,
          "media_count": 640,
          "favourites_count": 1530,
          "verified": false,
          "protected": false,
          "can_dm": true,
          "possibly_sensitive": false,
          "bio_urls": ["https://harborline.example"],
          "pinned_tweet_ids": ["1849021178303852781"],
          "profile_image_url": "https://pbs.twimg.com/profile_images/1427/hl.jpg",
          "profile_background_image_url": "https://pbs.twimg.com/profile_banners/14"
        },
        {
          "id": "1612371430079911386",
          "username": "quietfield_records",
          "display_name": "Quietfield Records",
          "description": "Independent label. Vinyl, tapes, late nights.",
          "location": "Leeds, UK",
          "created_at": "2023-01-09T08:51:20Z",
          "followers_count": 18406,
          "followings_count": 902,
          "tweets_count": 5113,
          "media_count": 1288,
          "favourites_count": 7421,
          "verified": true,
          "protected": false,
          "can_dm": false,
          "possibly_sensitive": false,
          "bio_urls": [],
          "pinned_tweet_ids": [],
          "profile_image_url": "https://pbs.twimg.com/profile_images/1612/qf.jpg",
          "profile_background_image_url": ""
        }
      ]
    }
    
  3. ユーザー名か ID で突き合わせ、並び順では突き合わせない。 3つの名前を送って、返ってきたプロフィールは2件でした。deleted_account_2019 には公開アカウントがないため、users から除かれています。ユーザー名は小文字にして比較してください。X は Harborline_Analytics と harborline_analytics を同じアカウントとして扱います。

  4. ID があるなら、ID で送る。 同じエンドポイントは user_ids も受け付け、1リクエストあたり最大100件です。ID は名前が変わっても変わらないので、繰り返し取得し直すリストには ID が最適です。

    import requests
    
    URL = "https://api.sorsa.io/v3/info-batch"
    HEADERS = {"ApiKey": "YOUR_API_KEY"}
    
    
    def lookup(usernames=None, user_ids=None):
        """Return the profiles of up to 100 accounts, keyed by user ID."""
        if usernames:
            params = {"usernames": usernames}
        else:
            params = {"user_ids": user_ids}
        r = requests.get(URL, headers=HEADERS, params=params, timeout=30)
        r.raise_for_status()
        return {u["id"]: u for u in r.json().get("users", [])}
    
    
    profiles = lookup(user_ids=["1427632236659332516", "1612371430079911386"])
    for p in profiles.values():
        print(p["username"], p["followers_count"], p["created_at"][:10])
    

401 はキーが間違っていること、403 はキーがない、またはリクエスト残量がないこと、429 は1秒に20リクエストを超えたことを示します。429 のときは1秒待ってから、そのチャンクを送り直してください。失敗したリクエストは課金されません。1アカウントだけなら、GET /info(新しいタブで開きます) でもユーザー名、ユーザー ID、プロフィールリンクから同じレコードを取得できます。ただし2アカウント以上なら、バッチ呼び出しのほうが同じ1リクエストで済みます。

#プロフィールレコードの内容

GET /info-batch のプロフィールには19個のフィールドがあり、すべてのフィールドがどの呼び出しでも返ります。次の表は、同じ値に公式 X API が使う名前を併記したもので、コードを一方の API からもう一方へ移すときに役立ちます。X は5つのカウントを public_metrics オブジェクトの中に入れ、ほとんどのフィールドは user.fields で指定したときだけ返し、投稿数を post_count、固定された投稿を pinned_post_id と呼ぶようになりました。

Sorsa API のフィールド公式 X API のフィールド内容
idid永続的なユーザー ID(文字列)
usernameusername現在のハンドル(@ なし)
display_namenameプロフィールに表示される名前
descriptiondescription自己紹介のテキスト
locationlocationプロフィールに入力された所在地
created_atcreated_at登録日(ISO 8601)
followers_countfollowers_count(public_metrics 内)現在のフォロワー数
followings_countfollowing_count(public_metrics 内)フォロー中のアカウント数
tweets_countpost_count(public_metrics 内)投稿、リプライ、リポストの合計
media_countmedia_count(public_metrics 内)投稿した写真と動画の数
favourites_countlike_count(public_metrics 内)アカウントがいいねした投稿の数
verifiedverified認証バッジの有無
protectedprotected投稿が非公開かどうか
can_dmreceives_your_dmダイレクトメッセージを受け付けるか
possibly_sensitiveなしX がセンシティブなアカウントとして扱っているか
bio_urlsurl、entities自己紹介とプロフィールのリンク
pinned_tweet_idspinned_post_id固定された投稿の ID
profile_image_urlprofile_image_urlアイコン画像
profile_background_image_urlprofile_banner_urlヘッダー画像
  • id

    公式 X API のフィールド
    id
    内容
    永続的なユーザー ID(文字列)
  • username

    公式 X API のフィールド
    username
    内容
    現在のハンドル(@ なし)
  • display_name

    公式 X API のフィールド
    name
    内容
    プロフィールに表示される名前
  • description

    公式 X API のフィールド
    description
    内容
    自己紹介のテキスト
  • location

    公式 X API のフィールド
    location
    内容
    プロフィールに入力された所在地
  • created_at

    公式 X API のフィールド
    created_at
    内容
    登録日(ISO 8601)
  • followers_count

    公式 X API のフィールド
    followers_count(public_metrics 内)
    内容
    現在のフォロワー数
  • followings_count

    公式 X API のフィールド
    following_count(public_metrics 内)
    内容
    フォロー中のアカウント数
  • tweets_count

    公式 X API のフィールド
    post_count(public_metrics 内)
    内容
    投稿、リプライ、リポストの合計
  • media_count

    公式 X API のフィールド
    media_count(public_metrics 内)
    内容
    投稿した写真と動画の数
  • favourites_count

    公式 X API のフィールド
    like_count(public_metrics 内)
    内容
    アカウントがいいねした投稿の数
  • verified

    公式 X API のフィールド
    verified
    内容
    認証バッジの有無
  • protected

    公式 X API のフィールド
    protected
    内容
    投稿が非公開かどうか
  • can_dm

    公式 X API のフィールド
    receives_your_dm
    内容
    ダイレクトメッセージを受け付けるか
  • possibly_sensitive

    公式 X API のフィールド
    なし
    内容
    X がセンシティブなアカウントとして扱っているか
  • bio_urls

    公式 X API のフィールド
    url、entities
    内容
    自己紹介とプロフィールのリンク
  • pinned_tweet_ids

    公式 X API のフィールド
    pinned_post_id
    内容
    固定された投稿の ID
  • profile_image_url

    公式 X API のフィールド
    profile_image_url
    内容
    アイコン画像
  • profile_background_image_url

    公式 X API のフィールド
    profile_banner_url
    内容
    ヘッダー画像
Xのプロフィール レコードのフィールド HA Harborline Analytics @harborline_analytics 港湾・海運データを毎週チャート化。 ロッテルダム harborline.example 2021年8月登録 418 フォロー中3,912 フォロワー 投稿2,276件 display_name username description location bio_urls created_at followings_count, followers_count tweets_count profile_image_url profile_background_image_url すべてのレコードにあり、カードには非表示: id, verified, protected, can_dm, possibly_sensitive, media_count, favourites_count, pinned_tweet_ids
公開プロフィールカードにあるものはすべてフィールドとして届くので、1レコードがスプレッドシートの1行になります。

プロフィールレコードに含まれないものが2つあります。X が非公開にしているメールアドレスと電話番号、そしてアカウントの投稿です。X の「このアカウントについて」に表示される国と、ユーザー名の変更回数は、GET /about(新しいタブで開きます) で取得します。こちらは1アカウントにつき1リクエストです。その国の情報がどこまで信頼できるかは、X の「アカウントの所在地」が意味するもののガイドで解説しています。

#アカウントの CSV をプロフィール情報で補強する

次のスクリプトは、スプレッドシートの1列に並んだアカウントを、完全なプロフィール表に変換します。accounts.csv を読み込みます。その account 列には、@ 付きまたは @ なしのユーザー名、プロフィールリンク、数値の ID が混在していても構いません。出力は、19個のフィールドと取得時刻を含む profiles.csv、そして結果が空だったアカウントをすべて書き出した missing.csv です。

Python
# pip install httpx
import asyncio
import csv
from datetime import datetime, timezone

import httpx

URL = "https://api.sorsa.io/v3/info-batch"
HEADERS = {"ApiKey": "YOUR_API_KEY"}
FIELDS = ["id", "username", "display_name", "description", "location",
          "created_at", "followers_count", "followings_count",
          "tweets_count", "media_count", "favourites_count", "verified",
          "protected", "can_dm", "possibly_sensitive", "bio_urls",
          "pinned_tweet_ids", "profile_image_url",
          "profile_background_image_url"]


def normalize(cell):
    """Turn a username, @name, link or ID into (parameter, value)."""
    value = cell.split("?")[0].strip().rstrip("/").rsplit("/", 1)[-1]
    value = value.lstrip("@")
    if value.isdigit():
        return "user_ids", value
    return "usernames", value.lower()


async def fetch(client, kind, chunk):
    for attempt in range(3):
        r = await client.get(URL, params={kind: chunk})
        if r.status_code == 429:          # over 20 requests a second
            await asyncio.sleep(1 + attempt)
            continue
        r.raise_for_status()
        return r.json().get("users", [])
    r.raise_for_status()


async def run(batches):
    async with httpx.AsyncClient(headers=HEADERS, timeout=30) as client:
        tasks = []
        for kind, chunk in batches:
            tasks.append(asyncio.create_task(fetch(client, kind, chunk)))
            await asyncio.sleep(1 / 20)   # 20 requests per second
        return await asyncio.gather(*tasks)


with open("accounts.csv", newline="", encoding="utf-8") as f:
    cells = [row["account"] for row in csv.DictReader(f)
             if row["account"].strip()]

wanted = {"usernames": [], "user_ids": []}
for kind, value in dict.fromkeys(map(normalize, cells)):
    wanted[kind].append(value)
batches = [(kind, values[i:i + 100])
           for kind, values in wanted.items()
           for i in range(0, len(values), 100)]

stamp = datetime.now(timezone.utc).isoformat(timespec="seconds")
found, rows = set(), 0
with open("profiles.csv", "w", newline="", encoding="utf-8") as f:
    out = csv.DictWriter(f, fieldnames=FIELDS + ["fetched_at"])
    out.writeheader()
    for users in asyncio.run(run(batches)):
        for u in users:
            found.update({u["id"], u["username"].lower()})
            row = {k: u.get(k) for k in FIELDS}
            for k in ("bio_urls", "pinned_tweet_ids"):   # lists to text
                row[k] = " ".join(u.get(k) or [])
            row["fetched_at"] = stamp
            out.writerow(row)
            rows += 1

missing = [v for values in wanted.values() for v in values
           if v not in found]
with open("missing.csv", "w", newline="", encoding="utf-8") as f:
    csv.writer(f).writerows([[v] for v in missing])
print(rows, "profiles;", len(missing), "not found")

2万5,000アカウントのリストは、250リクエストで約13秒で処理できます。profiles.csv をスプレッドシートで開くときは、id を文字列として扱ってください。Excel は数値の15桁までしか保持しませんが、ユーザー ID は最大19桁あります。リトライや保存のパターンは Python での Twitter API のガイドにさらに載っています。ID への変換だけが必要なリストについては、ユーザー名から Twitter ユーザー ID を取得のガイドをご覧ください。

#リストを更新して変化を追跡する

プロフィールの取得は、ある時点のスナップショットです。実行のたびにその瞬間のカウントが記録されるので、同じリストを定期的に実行すれば、スナップショットが履歴になります。最初の実行後は、profiles.csv の id 列でアカウントを取得し直します。ID は変わらないので、名前が変わったアカウントも、新しいユーザー名で返ってきます。

2つのスナップショットを ID で比較すると、フォロワーの増減、名前の変更、消えたアカウントがわかります。

Python
import csv


def load(path):
    with open(path, newline="", encoding="utf-8") as f:
        return {row["id"]: row for row in csv.DictReader(f)}


old = load("profiles-2026-11-01.csv")
new = load("profiles-2026-11-02.csv")

for user_id, now in new.items():
    then = old.get(user_id)
    if then is None:
        continue                        # added to the list since
    if now["username"] != then["username"]:
        print(f"renamed: @{then['username']} is now @{now['username']}")
    gained = int(now["followers_count"]) - int(then["followers_count"])
    if gained:
        print(f"@{now['username']}: {gained:+,} followers")

gone = sorted(old.keys() - new.keys())
print(len(gone), "accounts no longer returned:", gone[:10])

返ってこなくなったアカウントは、前回の実行以降に凍結、削除、または利用不可になったものです。リードリストやクリエイター名簿を毎日スナップショットする場合は、2つの API の費用差が最も急速に開きます。X は同じプロフィールを UTC の1日ごとに課金し直すのに対し、Sorsa API は100件のリクエスト単位で課金するからです。次のツールで更新の計画を立ててみてください。

10K
取得の頻度
公式X API(月額)
$3,000
300Kプロフィールの取得、1件$0.010。Xは同じプロフィールを、UTCの日ごとに再び課金します。
Sorsa API(月額)
最安 $4.20
3,000リクエスト(各100プロフィール)、1,000リクエストあたり$1.40、最上位プランの料金です。

月3,000リクエストは、Starterプランの10Kに収まります。1回の実行は100リクエストで、毎秒20リクエストなら約5秒です。公式X APIは15分あたり300件の取得なので、1つのウィンドウ内で終わります。

リストの規模と更新頻度を選んでください。どちらのカードにも、1か月の費用が表示されます。

そもそも注目すべきアカウントを見つけるには、Twitter でリードを見つける方法のガイドが X の検索からリードリストを作る手順を説明しています。Twitter フォロワー API なら、任意のアカウントのフォロワーを1ページ200件ずつ、完全なプロフィール付きで取得できます。

#プロフィール一括取得の費用と所要時間

公式 X API での一括取得は1,000プロフィールあたり$10.00、Sorsa API では1,000件あたり$0.014からです。Sorsa API は、含まれる各プロフィールではなく、100件のリクエストに対して課金するためです。

取得するプロフィール数

公式 X API

$10,000

100万 プロフィールの場合

1プロフィール $0.010

Sorsa API

$14から

100万 プロフィールの場合

1,000件あたり$0.014から

コストは700分の1以下

もう1つの違いは時間です。公式 X API では、1つのアプリが15分に送れる取得リクエストは300回です。そのため100件ずつ取得しても、100万プロフィールには約8時間20分かかります。Sorsa API は、無料アカウントを含む全プランで毎秒20リクエスト、つまり毎秒2,000プロフィールです。次の表で、4つのリスト規模について両者を並べて比較します。

プロフィール数Sorsa API の費用(から)Sorsa API の所要時間公式 X API の費用公式 X API の所要時間
1万$0.14約5秒$10015分のウィンドウ1つ以内
10万$1.40約50秒$1,000約50分
50万$7.00約4分$5,000約4時間
100万$14.00約8分$10,000約8時間20分
  • 1万

    Sorsa API の費用(から)
    $0.14
    Sorsa API の所要時間
    約5秒
    公式 X API の費用
    $100
    公式 X API の所要時間
    15分のウィンドウ1つ以内
  • 10万

    Sorsa API の費用(から)
    $1.40
    Sorsa API の所要時間
    約50秒
    公式 X API の費用
    $1,000
    公式 X API の所要時間
    約50分
  • 50万

    Sorsa API の費用(から)
    $7.00
    Sorsa API の所要時間
    約4分
    公式 X API の費用
    $5,000
    公式 X API の所要時間
    約4時間
  • 100万

    Sorsa API の費用(から)
    $14.00
    Sorsa API の所要時間
    約8分
    公式 X API の費用
    $10,000
    公式 X API の所要時間
    約8時間20分

「から」の価格は最大プランの料金で、1,000リクエストあたり$1.40です。最小の Starter プランでは、1,000プロフィールが$0.049です。どのプランでも課金の仕組みは同じで、1リクエストで最大100プロフィールを返し、失敗したリクエストは課金されません。

知っておきたいこと

チャンクは満杯にして送ってください。3アカウントのリクエストも100アカウントのリクエストも、料金は同じです。アカウントを1件ずつ送る処理は、必要な額の100倍を払うことになります。

#最初の10,000件のプロフィールを取得する

プロフィールの一括取得は、100アカウントにつき1リクエストに行き着きます。公式 X API では、そのリクエストが$1.00かかり、300回ごとに15分のウィンドウを待つことになります。X アカウントのリストをプロフィール情報で補強するなら、Sorsa API を選んでください。GET /info-batch は1リクエストで100件の完全なプロフィールを、1,000件あたり$0.014から、毎秒20リクエストで返します。必要なのはキー1つで、開発者アカウントは不要です。新規アカウントの100回分の無料リクエストで、最初の10,000件のプロフィールを取得できます。

#よくある質問

Twitter プロフィールを一括取得するには、どの API を使えばよいですか?

Twitter(X)API 兼スクレイピングツールである Sorsa API を使います。GET /info-batch エンドポイントは1リクエストで100件の完全なプロフィールを返し、料金は1,000件あたり$0.014からです。公式 X API は1,000件あたり$10.00です。全プランで毎秒20リクエストに対応し、開発者アカウントや OAuth の代わりに API キー1つで利用でき、19個のプロフィールフィールドをすべての呼び出しで返します。新規アカウントには100回分の無料リクエストが付き、10,000プロフィール分に十分です。

1回のリクエストで何件の Twitter プロフィールを取得できますか?

最大100件です。Sorsa API の GET /info-batch は1リクエストでユーザー名または ユーザー ID を100件受け付けます。公式 X API の GET /2/users/by と GET /2/users も同じ100件です。1万アカウントのリストは、どちらの API でも100回の呼び出しになります。違うのは料金と速度です。100プロフィールあたり、公式 X API は$1.00、Sorsa API は$0.0014からです。ペースは、公式 X API が15分に300回、Sorsa API が毎秒20回です。

Twitter プロフィールを一括取得する無料の方法はありますか?

公式 X API に無料プランはなく、最初の呼び出しからプロフィール1件につき$0.010かかります。Sorsa API は新規アカウントすべてに、有効期限なし・カード不要の100回分の無料リクエストを付与します。GET /info-batch なら、10,000プロフィール分です。1、2件のアカウントを見るだけなら、無料の Twitter アカウント比較ツールで、登録なしで完全なプロフィールを確認できます。

一括取得の結果に、一部のアカウントがないのはなぜですか?

バッチ取得が返すのは、見つかったアカウントだけです。入力ミスのユーザー名、変更されたユーザー名、凍結または削除されたアカウントには公開プロフィールがないため、リクエストが失敗するのではなく、レスポンスから除かれます。結果はユーザー ID か小文字のユーザー名で突き合わせ、残りは別のリストに書き出し、名前が変わったアカウントはユーザー ID で取得し直してください。

アカウントの国やメールアドレスを一括で取得できますか?

国は取得できますが、メールアドレスは取得できません。Sorsa API の GET /about は、X の「このアカウントについて」に表示される国、ユーザー名の変更回数、最後の変更日を返します。1アカウントにつき1リクエストです。メールアドレスと電話番号は X では非公開のため、Sorsa API でも公式 X API でも、プロフィール取得では返りません。

#検証方法

2026年11月2日に、公開されている Sorsa API リファレンスの /info-batch、/info、/about の項目を読み、このページのリクエストとフィールドはすべてそこから書きました。キーを使った実行はしていません。サンプルのレスポンスは、リファレンスのレスポンス形式に沿った架空のアカウントを使っています。同じ日に、docs.x.com の X のユーザー取得、料金、レート制限のページを読み、公式 X API のエンドポイント、料金、制限を確認して、表の費用と所要時間をその数値から計算しました。

Sorsa APIチーム 読み取り専用のX(Twitter)APIとスクレイピングツール、Sorsa APIを開発・運営しています。2022年から本番稼働し(旧TweetScout API)、累計60億リクエスト以上を処理しています。 Sorsa APIについて

変更点
  • 初公開。