تصور کنید در عرض سه هفته، ۵.۹۴ میلیارد ویدیو، ۳.۲۳ میلیارد پروفایل سازنده و ۲.۸ میلیارد کامنت را به دیتابیس خود منتقل کنید. این حجم عظیم از دادهها نه از طریق ابزارهای رایج، بلکه با هدف قرار دادن API خصوصی HTTP+JSON اپلیکیشن اندروید تیکتاک استخراج شده است. این سیستم بهطور خاص روی API مورد استفاده توسط com.zhiliaoapp.musically متمرکز شده است.
طبق یک راهنمای فنی که در ۳ سپتامبر ۲۰۲۶ توسط tiktok-api.seeksocial.io منتشر شد، این API موبایلی بسیار سریعتر و پایدارتر از رابطهای وب است و دادههای بسیار بیشتری را بازمیگرداند. اکثر ابزارهای استخراج داده (Scrapers) بر پایه مرورگرهای بدون رابط کاربری (Headless Browsers) یا نقاط اتصال وب عمومی هستند که کند بوده و اغلب فیلدهای حیاتی دادهها را نمایش نمیدهند. اما اپلیکیشن اندروید از لایهای خصوصی ارتباط برقرار میکند که برای دسترسی به آن، باید چهار شرط امنیتی بهطور همزمان برقرار باشد.
اگر حتی یکی از این شروط برقرار نباشد، سرور یک «بلاک نرم» (Soft Block) صادر میکند؛ یعنی کد موفقیت HTTP 200 را میفرستد اما بدنه پاسخ کاملاً خالی است. این طراحی باعث میشود عیبیابی تقریباً غیرممکن شود، چون هیچ پیام خطایی وجود ندارد، هیچ کد وضعیت (Status Code) خاصی صادر نمیشود و هیچ صفحه چالشی (Challenge Page) برای تحلیل وجود ندارد. در این حالت، لاگهای شما سبز میمانند، اما دیتابیس شما با هیچ (Nothing) پر میشود.
همانطور که در تحلیلهای پیشین ما دربارهی امنیت مدلهای بازمتن و استخراج دادههای عظیم اشاره کردیم، لایههای امنیتی سختافزاری در حال جایگزینی با متدهای سادهی احراز هویت هستند.
چهار دروازه دسترسی
برای پرسوجو از این API، درخواست باید از چهار لایه اعتبارسنجی متمایز عبور کند. اگر هر یک از این موارد — از یک ثابت چرخش گرفته تا ترتیب بایتها، هاست یا مجموعه رمزنگاری — اشتباه باشد، نتیجه همان پاسخ خالی ۲۰۰ است. هیچ امتیاز جزئی یا حلقه بازخوردی وجود ندارد که به شما بگوید کدام دروازه مانع دسترسی شما شده است.
- اعتبارنامههای دستگاه: شما نمیتوانید یک
device_idتصادفی اختراع کنید. باید یک پروفایل گوشی پذیرفتنی را از طریق نقطه اتصال/service/2/device_register/با یکdevice_id(۱۹ رقمی) و یکiid(شناسه نصب) مبادله کنید. این فرآیند نیازمند یک سند JSON است که با TTEncrypt (یک تبدیل در سطح بایت با برنامه زمانبندی کلید ثابت) رمزنگاری شده و به صورتapplication/octet-stream;tt-data=aارسال شود. بدنه ثبتنام باید از نظر داخلی سازگار باشد؛ برای مثال، یک گوشی سامسونگ SM-A136U باید رزولوشن خاص (۱۰۸۰*۲۲۸۰)، DPI (۴۴۰) و ABI (arm64-v8a) داشته باشد. سیستم از کاتالوگی شامل حدود ۲۵۰ پروفایل واقعی دستگاههای اندرویدی و یک جدول اپراتور شامل ۲۰۰۰ جفت MCC/MNC استفاده میکند تا اطمینان حاصل کند که گوشی و اپراتور بهطور منطقی در کشور هدف وجود دارند. - امضاهای درخواست: هر درخواست به یک امضای پیچیده نیاز دارد. هدر X-Argus یک پیام protobuf در فرمت wire proto3 است که از یک خط لوله رمزنگاری دو مرحلهای شامل Simon-128/256 و AES-128-CBC عبور میکند. این امضا ۳۸ پارامتر رایج را که توصیفکننده گوشی، اپراتور، منطقه و نسخه اپلیکیشن هستند، پوشش میدهد. ترتیب پارامترها ثابت است؛ استفاده از مرتبسازی الفبایی (مانند
url.Values.Encode()در زبان Go) منجر به تولید امضایی نامعتبر میشود. این protobuf شامل یکSignCountاست؛ شمارندهای که نشان میدهد این نصب چند درخواست ارسال کرده است. اسکریپتی که این مقدار را در هر درخواست به صفر ریست میکند، یک الگوی آماری واضح ایجاد میکند که بایتدنس (ByteDance) میتواند آن را در مجموع شناسایی کند. - میزبانی منطقهای: تیکتاک API خود را بین مراکز داده منطقهای مانند
alisg(سنگاپور)،useast1aوuseast5تقسیم کرده است. نقاط اتصال مختلف فقط روی هاستهای خاصی پاسخ میدهند. برای مثال، جزئیات پروفایل ممکن است برای دستگاههای جدید فقط توسط هاستuseast5ارائه شود، در حالی کهmusic/detailممکن است فقط رویuseast1aپاسخ دهد. هاست یک ویژگی مربوط به هر مسیر (Route) است و نه یک URL پایه جهانی. علاوه بر این، منطقه ثبتشده دستگاه بر محتوای نقاط اتصال محدود به منطقه، مانند صداهای ترند شده و قفسههای دستهبندی، تأثیر میگذارد. - اثر انگشت TLS: سرور پیام ClientHello را بازرسی میکند. کتابخانههای استاندارد مانند
crypto/tlsدر زبان Go فوراً شناسایی میشوند زیرا اثر انگشت JA3 آنها (که MD5 نسخه TLS، رمزها، افزونهها، منحنیهای بیضوی و فرمتهای نقطه است) با یک گوشی مطابقت ندارد. سیستم باید از uTLS برای تقلید از اثر انگشت BoringSSL مورد استفاده در OkHttp اندروید (مثلاًutls.HelloAndroid_11_OkHttp) استفاده کند. مقدارNextProtosباید رویhttp/1.1پین شود؛ مذاکره برای h2 اغلب منجر به اتصالی میشود که نمیتوان روی آن ارتباط برقرار کرد.
راز فعالسازی
ثبت دستگاه به تنهایی برای دادههای باارزش کافی نیست. نویسنده دریافت که نقطه اتصال /aweme/v1/user/profile/other/ بدنههای خالی برمیگرداند مگر اینکه دستگاه ابتدا یک تماس تلهمتری به /service/2/app_alert_check/ ارسال کند.
این «تماس استارتآپ» شامل یک بلوک tt_info است — تقریباً شصت جفت کلید=مقدار (شامل GAID، منطقه زمانی، اپراتور، ABI، لوکال و یک UUID درخواست) که با TTEncrypt رمزنگاری و به صورت base64url کدگذاری شدهاند. این اقدام به بایتدنس سیگنال میدهد که دستگاه یک اپلیکیشن در حال اجراست و نه یک اسکریپت ثبتنام ساده. بدون این تک درخواست، دسترسی به پروفایلها فارغ از دقت امضا، در سطح ۰٪ باقی میماند. نتیجه تجربی بسیار واضح بود: دستگاههایی که فقط ثبتنام کرده بودند، نرخ موفقیت ۰ از ۳۶۰ در پروفایلها داشتند، در حالی که دستگاههای دارای تماس استارتآپ به نرخ ۱۰۰ از ۱۰۰ رسیدند.
برای تضمین اینکه یک دستگاه واقعاً توانمند است، سیستم از یک خط لوله سهمرحلهای استفاده میکند:
۱. ثبتنام: مبادله دادههای گوشی برای دریافت device_id و iid.
۲. فعالسازی: اجرای تماس استارتآپ app_alert_check.
۳. فیلتر بقا: یک «پروب پروفایل» که در آن دستگاه باید بتواند با موفقیت پروفایل یک سازنده شناختهشده را بخواند تا اجازه ورود به استخر دادهها را پیدا کند.
تقریباً ۶۰ تا ۹۵ درصد تلاشها بسته به کیفیت پروکسی از این فرآیند جان سالم به در میبرند. بدون این فیلتر، استخر دستگاهها بهطور نامرئی تخریب میشود زیرا دستگاههای مرده پاسخهای ۲۰۰ خالی برمیگردانند و باعث میشوند نرخ موفقیت در طول چند روز بدون هیچ لاگ خطایی کاهش یابد.
ابزارهای رمزنگاری غیرمتعارف
تیکتاک برای سختتر کردن مهندسی معکوس و جلوگیری از شناسایی از طریق فراخوانیهای کتابخانههای استاندارد، از انتخابهای رمزنگاری غیر استاندارد استفاده میکند:
- SM3: استاندارد ملی رمزنگاری چین (GB/T 32905-2016). این یک هش ۲۵۶ بیتی با تابع فشردگی مشابه SHA-256 است اما دو برنامه زمانبندی گسترش پیام موازی (W و W') دارد. این استاندارد در اکثر کتابخانههای غربی وجود ندارد و بسیاری از پیادهسازیهای مرجع آن در ورودیهای خاص دچار خطا میشوند.
- Simon و Speck: رمزهای بلوکی سبکوزن ARX (جمع، چرخش، XOR) که توسط NSA در سال ۲۰۱۳ منتشر شدند. آنها از S-boxها و جداول جستجو اجتناب میکنند که باعث میشود روی سختافزارهای ARM کارآمد باشند و در برابر کانالهای جانبی زمانبندی حافظه پنهان (Cache-timing) مقاوم باشند. تابع دور Speck تنها دو خط کد است. دلیل استفاده از اینها این است که به چند صد بایت کد ARM کامپایل میشوند و بهراحتی میتوان در پیادهسازی آنها (مثلاً در ترتیب کلمات یا endianness در برنامه زمانبندی کلید) اشتباهات ظریفی مرتکب شد.
- X-Ladon: یک دروازه سادهتر که از رشتهای متصل با خط تیره شامل
<khronos>-<license_id>-<aid>استفاده میکند که از طریق Speck-128/256-ECB با کلیدی مشتق شده از MD5 بایتهای تصادفی و App ID رمزنگاری شده است. این یک فیلتر ارزان برای مسدود کردن کسانی است که اپلیکیشن را تحلیل نکردهاند. - TTEncrypt: یک رمزنگاری بدنه غیر استاندارد که برای محمولههای ثبتنام و بلوکهای فعالسازی استفاده میشود. این یک تبدیل بایت با کلید ثابت و یک جدول کوچک است که برای متوقف کردن بازرسیهای ترافیکی آماتور طراحی شده است، نه برای ارائه امنیت سطح بالا.
مقیاسپذیری تا میلیاردها رکورد
برای رسیدن به مقیاس میلیاردها رکورد، سیستم یک استراتژی خاص پروکسی را پیاده میکند. محدودیت نرخ (Rate Limit) بر اساس IP خروجی است. در یک درگاه پروکسی چرخان، یک اتصال TCP جدید معمولاً یک IP خروجی جدید میدهد. با این حال، HTTP keep-alive استاندارد، کلاینت را برای طول عمر اتصال به یک IP پین میکند.
اگر درخواستی دچار «بلاک نرم» شود، تلاش مجدد با استفاده از keep-alive از همان IP مسدود شده استفاده میکند و بودجه تلاش مجدد را بیهوده میکند. با تنظیم DisableKeepAlives: true در هنگام تلاشهای مجدد، سیستم مجبور به ایجاد یک اتصال TCP جدید و دریافت IP خروجی جدید میشود. این اقدام نرخ موفقیت را از ۸۸.۲٪ به ۹۹.۳٪ ارتقا داد.
برای جلوگیری از «طوفان دستدادن» (Handshake Storm) — جایی که درگاه پروکسی به دلیل تعداد زیاد دستدادنهای TLS، تونلها را رد کرده و خطای 466 Too Many Requests برمیگرداند — سیستم از یک رویکرد ترکیبی استفاده میکند: keep-alive برای اولین تلاش و DisableKeepAlives فقط برای تلاشهای بعدی. این تضمین میکند که در حالت عادی هزینهای برای دستدادن پرداخت نشود و چرخش دقیقاً در جایی اتفاق بیفتد که لازم است.
قابلیتهای نقاط اتصال و دادهها
API موبایل فیلدهایی را ارائه میدهد که بهطور کامل در نسخه وب غایب هستند. سیستم ۲۴ نقطه اتصال را مستند کرده است که به شرح زیر دستهبندی میشوند:
- سازندگان (Creators)
/v1/user/posts: ویدیوها را به همراه شیء کامل نویسنده برمیگرداند. یک درخواست، ۲۰ ویدیو و ۲۰ رکورد سازنده را فراهم میکند./v1/user/info: پروفایل کامل، شاملbio_email(در حدود ۱٪ سازندگان) و پرچمهای تجاری./v1/user/followersو/v1/user/following: لیست حسابها (در صورتی که مخفی نباشند). برخی در صورت مخفی بودن لیست، کد وضعیت3002060را برمیگردانند./v1/user/recommended: گراف سازندگان مشابه تیکتاک.
- ویدیوها (Videos)
/v1/video/info: رسانه، آمار، صدا، تگها و نویسنده./v1/video/comments: کامنتها به همراه شیء کاربر کامنتگذار./v1/video/comments/replies: درخت کامنتهای سطح دوم.
- صداها (Sounds)
/v1/music/info: جزئیات صدا شاملuser_count(تعداد کل ویدیوهایی که از این صدا استفاده کردهاند)./v1/music/postsو/v1/music/posts/fresh: ویدیوهای محبوب و جدیدترین ویدیوهای استفادهکننده از یک صدا./v1/music/trending: جدول صداهای ترند شده، محدود به منطقه دستگاه./v1/music/related: صداهای پیشنهادی برای یک ویدیوی خاص.
- کشف و جستجو (Discovery & Search)
/v1/hashtag/infoو/v1/hashtag/posts: جزئیات هشتگ و ویدیوهای مرتبط./v1/search/general: نتایج ترکیبی از سازندگان، ویدیوها و تگها./v1/search/users: تبدیل هندلها یا نامها بهuser_idعددی./v1/trending/categoriesو/v1/trending/effects: قفسههای «چه چیزی داغ است» و افکتهای ترند شده./v1/feed: فید For You ناشناس (که به دلیل خطاهای واقعی 429، نرخ موفقیت ضعیف ۱۰ تا ۲۵ درصدی دارد).
مقایسه فیلدهای داده:
| فیلد | مکان | در دسترس بودن |
|---|---|---|
statistics.collect_count |
هر ویدیو | همیشه (ذخیرهها) |
music.user_count |
هر صدا | همیشه (تعداد استفاده) |
author.ins_id |
نویسنده ویدیو | حدود ۲۶٪ سازندگان |
author.youtube_channel_id |
نویسنده ویدیو | حدود ۱۹٪ سازندگان |
bio_email |
user.info |
حدود ۱٪ سازندگان |
commerce_user_level |
user.info |
همیشه |
bio link |
فقط وب | ۰٪ (در API موبایل نیست) |
نویسنده مجموعهای از دادههای ۴.۵ میلیارد ویدیو را در Hugging Face در آدرس huggingface.co/datasets/kuben-developer/tiktok-videos-4b آپلود کرده است که شامل کپشنها، تعداد بازدیدها، تعداد لایک/کامنت/ذخیره، شناسههای صدا، کشور و زمان انتشار است.
زیرساخت و ذخیرهسازی
جمعآوری میلیاردها ردیف داده باعث ایجاد حالتهای شکست در ذخیرهسازی میشود که با فرآیند جمعآوری متفاوت است. سیستم از ClickHouse برای ذخیرهسازی حجم بالا استفاده میکند و تصمیمات معماری خاصی برای جلوگیری از فروپاشی سیستم گرفته است:
- پارتیشنبندی: استفاده از باقیمانده ساده (Modulus) یک ID برای پارتیشنبندی میتواند منجر به توزیع ناعادلانه شود. در یک جدول، اختلاف ۴۳ برابری بین پارتیشنها مشاهده شد. هش کردن ID قبل از اعمال Modulus، توزیع را یکنواخت میکند.
- منطق بهروزرسانی: از
ReplacingMergeTreeبرای بهروزرسانیها استفاده میشود، اما این متد کل ردیف را جایگزین میکند. بهروزرسانیهای جزئی اگر بهدرستی مدیریت نشوند، میتوانند بهطور بیصدا فیلدها را خالی کنند. - نگهداری سیستم: جداول
text_logوtrace_logدر ClickHouse میتوانند بهطور نامحدود رشد کنند. در یک مورد، این لاگها به ۲۴۳ گیگابایت رسیدند و یک حجم ۷ ترابایتی را پر کردند و تمام عملیات نوشتن را متوقف کردند. تعریف TTL (زمان انقضا) روی جداول سیستم اجباری است.
اقتصاد پروکسیها
برای این حجم از کاری، صورتحساب بر اساس مصرف (هر گیگابایت) ناکارآمد است زیرا نقاط اتصال باارزش، پاسخهای حجیمی برمیگردانند (مثلاً یک صفحه از سازندگان پیشنهادی ۲.۹ مگابایت است). اشتراکهای ماهانه ثابت توصیه میشوند:
- لایه دیتاسنتر (حدود ۱۵۰ دلار در ماه): پشتیبانی از حدود ۱۰۰ ترد همزمان با سرعت ۲۰۰ مگابیت بر ثانیه. برای میلیونها رکورد کافی است.
- لایه مسکونی (حدود ۹۵۰ دلار در ماه): استخر مسکونی بدون محدودیت حجم. برای جمعآوری در مقیاس میلیاردی ضروری است.
در ۱۰۰ ترد و سرعت ۲۰۰ مگابیت بر ثانیه، سیستم بسته به نقطه اتصال با گلوگاههای متفاوتی روبرو میشود. برای پروفایلهای سازنده (۹.۵ کیلوبایت)، محدودیت تعداد تردهاست (حدود ۱۴۰ در ثانیه). برای متادیتای ویدیو (۱.۱ مگابایت)، محدودیت سرعت خط است (حدود ۴۵۰ در ثانیه).
این تغییر در متدولوژی استخراج داده ثابت میکند که ارزشمندترین دادههای اجتماعی دیگر پشت چرخش حسابهای کاربری نیستند، بلکه پشت شبیهسازی دقیق سختافزاری پنهان شدهاند. برای توسعهدهندگان، این بدان معناست که عصر Wrapperهای ساده API به پایان رسیده و مرز جدید، شبیهسازی کامل دستگاه (Full-stack Device Emulation) است.
گام بعدی شما
- اگر توسعهدهنده هستید، بررسی کنید که آیا ابزارهای استخراج داده شما از اثر انگشت TLS (JA3) پشتیبانی میکنند یا خیر.
- برای پروژههای مقیاسبزرگ، به جای پرداخت حجمی، از پروکسیهای مسکونی با هزینه ثابت ماهانه استفاده کنید.
- در طراحی سیستمهای ذخیرهسازی حجیم، حتماً برای جداول لاگ سیستم در ClickHouse مقدار TTL تعریف کنید.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell و پردازش دادههای عظیم مراجعه کنید.




گفتگو