HN 日本語サマリー

← 一覧へ戻る
AI・機械学習

TikTokから45億件の投稿をスクレイピング

4.5B Posts Scraped from TikTok (tiktok-api.seeksocial.io)

36 pointsby TheOnlyWayUp27 コメント

要約

この記事は、TikTokのモバイルAPIを技術的に解析し、3週間で32億件のクリエイタープロファイル、59億件の動画、28億件のコメントを収集したシステムについて解説しています。デバイス登録、リクエスト署名、地域ホストの分割、TLSハンドシェイクのフィンガープリンティングといった技術的詳細を掘り下げ、そのAPIの速度と情報量の多さを強調しています。収集されたデータの一部はHugging Faceで公開されています。

全文翻訳

Technical guide · 24 endpoints · Measured Scraping TikTok's Mobile API TikTokのAndroidアプリは、Webエンドポイントよりも高速で、はるかに多くの情報を返すプライベートなHTTP+JSON APIと通信します。これは、デバイスがどのように登録され、リクエストがどのように署名され、地域ホストがどのように分割され、TLSハンドシェイクがどのようにフィンガープリントされるかについての技術ガイドです。それに基づいて構築されたシステムは、3週間で32億件のクリエイタープロファイル、59億件の動画、28億件のコメントを収集しました。 完全なコードと無料データセットを入手 これらの動画のうち45億件をHugging Faceにアップロードしました:キャプション、視聴数、いいね数、コメント数、保存数、サウンド、国、投稿時間。 huggingface.co/datasets/kuben-developer/tiktok-videos-4b 取得できるもの クリエイタープロファイル、クリエイターが投稿したすべての動画、フォロワーとフォローリスト、TikTok独自の類似クリエイターグラフ。完全な統計ブロックを含む完全な動画詳細。コメントとコメントの返信(各コメント投稿者のアカウント付き)。サウンド、それを使用している動画、トレンドサウンドチャート。ハッシュタグとその動画、最新または最も人気のあるもの。動画、クリエイター、サウンド全体でのキーワード検索。トレンドシェルフとカメラエフェクト。合計24のエンドポイントがあり、それぞれに測定された成功率があります。 約30分で読めます 測定は2026年9月に再実行されました Go 1.24 これは何ですか 現在見つかるほとんどすべてのTikTokスクレイパーは、ヘッドレスブラウザを駆動するか、公開Webエンドポイントにアクセスします。どちらも間違ったレイヤーです。遅く、壊れやすく、興味深いフィールドのほとんどが欠けています。Androidアプリはどちらも使用しません。com.zhiliaoapp.musicallyがスクロール時にヒットするのと同じプライベートHTTP+JSON APIと通信します。そのAPIは高速で安定しており、はるかに多くの情報を返します。 それにアクセスすることが難しい部分であり、それは特定の意味で難しいです。4つの完全に無関係なものが同時に正しくなければなりません:TikTokが発行したデバイス認証情報、有効なリクエスト署名、正しい地域ホスト、そして電話のように見えるTLSハンドシェイク。どれか一つでも間違えると、同じ応答が得られます:空のボディを持つクリーンなHTTP 200。エラーメッセージはありません。ステータスコードもありません。HTTPクライアントは成功を報告し、ログはグリーンを維持し、データベースは何も満たしません。4つのうちどれでつまずいているかを示す信号はありません。この記事では、これら4つすべてを説明し、その先に続く24のエンドポイントを文書化します。プリミティブの名前を挙げ、実際のパイプラインを示し、主張ではなく測定された数値を提供します。 4つのうちどれにもフィードバックループはありません。間違った回転定数、間違ったバイト順序、間違ったホスト、ハンドシェイクでの間違った暗号スイートはすべて同じ正しくフォーマットされたリクエストと空の応答を生成するため、分割できるエラーがなく、部分的なクレジットもありません。 スコープ 以下はすべて匿名デバイストラフィックです。このシステムにはログイン、アカウント、セッションCookieはありません。つまり、アカウントで制限されているもの(DM、プライベート動画、誰が何にいいねしたかなど)は範囲外であり、範囲外のままです。調整してもそこには到達できません。 リクエストの構造 まず、これらのリクエストの1つが実際にはどのようになるかを示します。これは実際の呼び出しで、識別値は短縮されています。 GET /aweme/v1/aweme/post/ ?# ── 何を求めているか ────────────────────────────── source=0 &user_id=6744630345964389381 &count=20 &max_cursor=1751028792000 &sort_type=0 &# ── 誰が尋ねているか:38パラメータ、順序が重要 ───────────── ts=1788361402&ac=mobile&ac2=lte &aid=473824 # アプリID:TikTok Lite &iid=7680617333853718293 # インストールID ← 登録から &device_id=7680616891110524437 # デバイスID ← 登録から &cdid=4a1d... # クライアント生成UUID &openudid=8f2c... # クライアント生成16バイト16進数 &device_brand=Samsung&device_type=SM-A136U&os_version=12&os_api=30 &resolution=1080*2280&dpi=440&host_abi=arm64-v8a &region=SG&carrier_region=SG&sys_region=SG&mcc_mnc=52506 &language=ja&app_language=ja&locale=ja-SG&timezone_name=Asia%2FSingapore &version_name=32.8.2&version_code=320820&manifest_version_code=320820 &_rticket=1788361402193&channel=googleplay&app_type=normal ヘッダー: user-agent: com.ss.android.ugc.tiktok.lite/320802 (Linux; U; Android 12; ...) x-tt-trace-id: 00-6a9f...-6a9f...-01 x-ss-req-ticket: 1788361402193 x-khronos: 1788361402 # タイムスタンプ x-ladon: XKp9... # Speck-128/256 x-argus: cQqbRZm8k1x... # 難しい方 x-gorgon: 0404b0d30000... # レガシーダイジェスト 単一のクリエイタータイムラインリクエスト。 折り畳み以下のすべてがデバイスIDです。 注意すべき3つの点。これらは後でつまづく原因となります。 URLの3分の2はデバイスIDです。38個の一般的なパラメータがハンドセット、キャリア、地域、アプリビルドを説明しています。これらは装飾ではありません。署名はそれらをカバーします。 device_idとiidはTikTokによって発行され、あなたが選択するものではありません。cdidとopenudidは、登録時にあなたが生成して送信するものです。この区別を間違えることが最初の壁です。 パラメータの順序は固定されています。署名はクエリ文字列をリテラルとしてハッシュするため、url.Values.Encode()(キーをアルファベット順にソートします)はサイレントに無効な署名を生成します。Goではクエリを手動で構築する必要があります。 用語(繰り返し現れるため): フィールド 内容 起源 aid アプリケーションID。1233はメインアプリ(musically)、473824はLite、1340はmusically_goです。異なるaidは異なる署名キーと異なるエンドポイントセットを意味します。 定数 device_id 永続的なデバイスID。19桁。 TikTok、登録時 iid インストールID。device_idとペアになります。 TikTok、登録時 cdid クライアントデバイスID。あなたが生成するUUID。 あなた openudid あなたが生成する16バイトの16進数。 あなた license_id X-Ladonキーのスケジューリングに使用。 定数(アプリごと) version_code アプリビルド。どのアウトエンドポイントが応答するかを制限します。 あなた 最初の空の200 正しく実装された署名者は、パラメータがバイトごとに一致する、キャプチャされたトラフィックに対して検証される出力を生成します。応答は依然としてこれです。 $ curl -sD- -o /tmp/body "https://api16-normal-c-alisg.tiktokv.com/aweme/v1/user/profile/other/?..." HTTP/1.1 200 OK content-type: application/json content-length: 0 x-tt-logid: 2026090117... server: TLB $ wc -c /tmp/body 0 /tmp/body 200 OK。0バイト。ステータスコードはありません。ボディがないためです。これはTikTokのソフトブロックであり、このAPIについて理解すべき最も重要なことです。これは403ではありません。429でもありません。チャレンジページでもありません。これは空のボディを含む成功したHTTP応答です。 つまり、誰もが最初に書くこのコードはサイレントに壊れています。 res = requests.get(url, headers=signed) if res.ok: # True. Always true. store(res.json()) # {} stored, no exception # six hours later: 400,000 rows in the database, all empty, # nothing in the error log, dashboard green デバッグが困難なのは、4つの無関係な障害がこれを引き起こすからです。 デバイスがアクティブ化されていません(§アクティベーション) 署名が間違っています(§ X-Argus) 間違った地域ホストに接続しています(§地域) TLSハンドシェイクが電話ではなくサーバーのように見えます(§ JA3) 応答には、どれが間違っているかを伝えるものはありません。エラーを読んでも分割できないのは、エラーがないからです。唯一の解決策は、4つすべてを修正し、それぞれを個別に測定することです。 デバイスIDの出所 デバイスIDを勝手に作成することはできません。TikTokは、ログホストの/service/2/device_register/から、もっともらしいハンドセットと引き換えにそれを発行します。リクエストボディはJSONドキュメント(アプリヘッダー、デバイスヘッダー、カスタムブロック)で、TTEncrypt(TikTok独自のボディ暗号、固定キーを持つシンプルなバイトレベル変換)で暗号化され、application/octet-stream;tt-data=aとして投稿されます。これは完全な署名セットとともに送信されるため、デバイスを取得する前に署名が機能している必要があり、署名にはデバイスが必要です。クライアント生成フィールドと、発行されたフィールドの代わりにゼロを使用してブートストラップします。 ボディの形状(重要な部分): { "magic_tag": "ss_app_log", "header": { // アプリのID:クエリ文字列のaidと一致する必要があります "aid": 473824, "package": "com.ss.android.ugc.tiktok.lite", "app_version": "32.8.2", "version_code": 320820, "sdk_version": "...", "gi