بعد إطلاق حملة، قد يرغب الفريق في التحقق من مقاطع الفيديو العامة التي تظهر في نتائج البحث عن كلمات محددة. يصعب تكرار البحث اليدوي ومقارنته بعد بضعة أيام. ويمكن لأداة جمع صغيرة تشغيل الطلبات نفسها وفق جدول زمني وأرشفة الاستجابات مع تاريخ الجمع وعبارة البحث، كي يتمكن المحلل من مراجعة السجلات وإعداد ملخصه الخاص.

يعرض هذا الدليل مسار عمل أرشفة باستخدام Python لحفظ نتائج البحث عن عبارات ثابتة. وعلى خلاف مراقبة وسوم أو حسابات بعينها، يعتمد أساس المقارنة هنا على تكرار عبارات البحث نفسها وحفظ لقطة منفصلة لكل استجابة. وتشير صفحة واجهة TikTok Scraper API من jsonscraper إلى العنوان الأساسي والمسار GET /searchVideo؛ وفي وثائق هذا المسار، تُمرَّر عبارة البحث في المعامل الإلزامي keyword.
المهمة وحدود القياس
لنفترض أن مسوّقاً يريد جمع نتائج البحث يومياً لعدة عبارات ثابتة: اسم منتج، وفئة، وصياغة لمشكلة عميل. يحفظ النظام وقت الجمع واستجابة واجهة API لكل طلب. وبعد فحص عينة من الاستجابة، يمكن إضافة توحيد للحقول الموجودة فعلياً في JSON، مثل معرّف الفيديو أو العدّادات العامة، إن وُجدت.
يجيب الأرشيف عن سؤال محدد: ما السجلات التي أعادها البحث بالعبارة المحفوظة أثناء هذا التشغيل؟ إذا احتوت الاستجابة على مقاييس، فقد تكشف الملاحظات المتكررة اختلاف القيم المسجلة في أوقات مختلفة. ويتعلق هذا الاختلاف باللقطات المرصودة والفترة الفاصلة بينها؛ لذا احفظ وقتَي الجمع والحقل نفسه لإجراء المقارنة.
احفظ الطلب مع الاستجابة. فتركيبة النتائج مرتبطة بعبارة بحث محددة ووقت جمع بعينه. لذلك يفيد الأرشيف في تتبع النتائج للطلبات المختارة، لا في تقديم عرض شامل لكل محتوى TikTok. وتساعد المعرّفات والاستجابات الأصلية والطوابع الزمنية على التحقق من مصدر كل صف في الجدول اللاحق.
تحقّق من المسار ومعاملاته
تحدّد خريطة مسارات TikTok API العنوان الأساسي https://tiktok.evelode.com والمسار GET /searchVideo. وتذكر مواصفات API الحالية أن keyword معامل إلزامي للبحث؛ وتشمل المعاملات الاختيارية cursor وcount وcache_timeout وdate_posted وsort_by وregion. ويُمرَّر license_key للمصادقة. كما تتوفر معلومات المسار في وثائق Python SDK.
يساعد المعاملان count وdate_posted على تحديد حجم الاستجابة والمرشح الزمني؛ ويقبل sort_by القيم الموثقة most-liked أو relevance أو date-posted. إذا استخدمت ترقيم الصفحات، فمرّر قيمة cursor التي حصلت عليها من الاستجابة السابقة كما هي، من دون احتسابها بنفسك. ولإعداد أرشيف يومي قابل للمقارنة، احفظ معاملات الطلب وإصدار الشيفرة التي تستخدمها بجانب البيانات.
يستخدم المثال أدناه قيمة صغيرة للمعامل count في تشغيل تجريبي، ومنطقة ثابتة هي US. تحقّق من طلب واحد ورمز حالة HTTP وبنية JSON قبل بدء الجمع اليومي. قد يحتوي مخطط الاستجابة على مقاطع الفيديو التي عُثر عليها ضمن tiktok.aweme_list أو ضمن tiktok.search_item_list، حيث يوجد كائن الفيديو في aweme_info؛ وتتعامل الشيفرة مع كلتا الصيغتين المرصودتين.
إعداد المشروع
أنشئ بيئة افتراضية وثبّت حزمة requests:
python -m venv .venv
source .venv/bin/activate
pip install requests
في PowerShell، يجري تفعيل البيئة بالأمر .venv\Scripts\Activate.ps1. اضبط المفتاح وقائمة عبارات البحث عبر متغيرات البيئة. استخدم الاسم الموثق لمتغير TikTok API، وهو JSONSCRAPER_TIKTOK_LICENSE_KEY:
export JSONSCRAPER_TIKTOK_LICENSE_KEY="ваш_ключ"
export TIKTOK_QUERIES="название продукта,категория товара,проблема клиента"
جمع اللقطات وحفظها
يرسل المثال طلباً واحداً لكل عبارة إلى المسار الموثق، ثم يحفظ JSON الأصلي ووقت الجمع والمعاملات المستخدمة. ويتضمن اسم الملف التاريخ وعبارة البحث. ويبقى المفتاح في البيئة ولا يُضمَّن في الأرشيف.
import json
import os
import re
import time
from datetime import datetime, timezone
from pathlib import Path
import requests
BASE_URL = "https://tiktok.evelode.com"
ENDPOINT = "/searchVideo"
LICENSE_KEY = os.environ["JSONSCRAPER_TIKTOK_LICENSE_KEY"]
QUERIES = [
item.strip()
for item in os.environ["TIKTOK_QUERIES"].split(",")
if item.strip()
]
OUT = Path("data")
OUT.mkdir(exist_ok=True)
def safe_name(text):
cleaned = re.sub(r"[^a-zA-Z0-9_-]+", "_", text).strip("_")
return cleaned[:80] or "query"
def fetch(query):
params = {
"license_key": LICENSE_KEY,
"keyword": query,
"count": 10,
"region": "US",
}
response = requests.get(
BASE_URL + ENDPOINT,
params=params,
timeout=60,
)
response.raise_for_status()
payload = response.json()
if payload.get("status") != "ok":
raise RuntimeError("API вернул статус, отличный от ok")
return payload
def extract_videos(payload):
tiktok = payload.get("tiktok") or {}
videos = list(tiktok.get("aweme_list") or [])
for item in tiktok.get("search_item_list") or []:
video = item.get("aweme_info") or {}
if video:
videos.append(video)
return videos
for query in QUERIES:
collected_at = datetime.now(timezone.utc).isoformat()
payload = fetch(query)
record = {
"collected_at": collected_at,
"query": query,
"request": {
"endpoint": ENDPOINT,
"keyword": query,
"count": 10,
"region": "US",
},
"videos_found": len(extract_videos(payload)),
"payload": payload,
}
filename = OUT / f"{collected_at[:10]}_{safe_name(query)}.json"
filename.write_text(
json.dumps(record, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(f"Сохранён ответ для запроса: {query}")
time.sleep(1)
print(f"Сохранено ответов: {len(QUERIES)}")
تنفّذ أداة الجمع البسيطة هذه طلباً واحداً لكل عبارة باستخدام count=10. ولجمع نطاق أوسع، أضف ترقيم الصفحات باستخدام cursor: واصل الطلبات بتمرير قيمة المؤشر الواردة في الاستجابة إلى أن تشير واجهة API إلى عدم وجود نتائج أخرى، وسجّل كل استجابة على حدة. يحدد المؤشر وعدد النتائج مسار الجمع المحدد؛ وتتيح ملفات JSON المحفوظة التحقق لاحقاً مما أعاده كل طلب.
يتحقق المثال من قيمة status الخارجية، ثم يقرأ الكائن tiktok. ويجمع العناصر من aweme_list، وكذلك من search_item_list[].aweme_info إن وُجدت هذه الصيغة. وقد تشمل الحقول المتاحة لمقطع الفيديو معرّفاً ووصفاً ومؤلفاً ورابطاً وإحصاءات؛ وقد تغيب بعض الحقول. لذا احفظ الاستجابة كاملة، وتحقّق من وجود كل حقل عند توحيد البيانات.
الفاصل الزمني البالغ ثانية واحدة هو مهلة بين طلبات البرنامج نفسه، وليس تصريحاً بشأن حدود الخدمة. اضبط وتيرة الطلبات وإعادات المحاولة بما يتوافق مع شروط الوصول والوثائق. والمعامل cache_timeout موثق للبحث؛ إذ يتيح تحديد مدة التخزين المؤقت بالثواني، فيما تعطل القيمة 0 التخزين المؤقت وفقاً للمواصفات. أضفه إلى الطلب عندما يناسب هذا السلوك سيناريو الاستخدام.
أضف توحيداً للبيانات استناداً إلى الاستجابة الفعلية
بعد التشغيل الأول، افتح الملف المحفوظ وافحص بنية payload. تجمع الدالة extract_videos في المثال العناصر من موضعين موثقين لصيغ البحث في الاستجابة. ابحث عن المفاتيح الدقيقة للحقول اللازمة للتحليل. إذا غاب حقل عن سجل بعينه، فاحفظه بوصفه قيمة مفقودة بدلاً من إدراج رقم مفترض.
لمعالجة البيانات لاحقاً، من الملائم إنشاء صف لكل كائن عُثر عليه، وإضافة collected_at وquery إليه. يمكن حفظ الحقول المؤكدة في ملف CSV أو قاعدة بيانات، مع إبقاء JSON الأصلي في الأرشيف. يتيح هذا الجمع إعداد جداول سهلة الاستخدام، مع إمكانية التحقق من مصدر كل سجل.
إذا أعادت واجهة API معرّفاً للفيديو، فاستخدمه لربط ملاحظات الفيديو نفسه بين عمليات التشغيل المختلفة. احتفظ بكل ملاحظة على حدة ولا تستبدل البيانات السابقة. وإذا لم يتوفر معرّف ثابت، فتحقّق أولاً من السمات التي تسمح بمطابقة السجلات، ولا تعتبر تطابق نص الوصف دليلاً مؤكداً.
قارن اللقطات وأعد التقرير
بعد توحيد البيانات، جمّع السجلات بحسب المعرّف الذي تحققت منه ورتّبها حسب وقت الجمع. ويمكن حساب الفرق بين قيمتين متتاليتين للحقول التي تمثل عدّادات باستخدام شيفرة عادية. فمثلاً، يعني الانتقال من 12 400 إلى 18 900 أن قيمة العدّاد تغيرت بمقدار 6 500 بين هاتين اللقطتين. اذكر في التقرير تاريخَي الرصد والحقل الأصلي كي يتمكن القارئ من التحقق من الحساب.
يمكن أن يتضمن الجدول النهائي عبارة البحث ومعرّف المنشور ووقت الجمع والحقول المختارة من الاستجابة. ويمكن تجميع الملخص بحسب الطلبات وترتيبه باستخدام عدّاد واحد تم التحقق منه. ينتج عن ذلك قائمة قابلة للتحقق من السجلات التي أعيدت، ليراجعها الفريق لاحقاً؛ أما الجدول أو الرسالة فنفّذهما في خطوة مستقلة بعد دراسة المخطط الفعلي.
ابدأ بحفظ ملفات JSON محلياً. وعندما يصبح الجمع منتظماً، انقل الصفوف الموحّدة إلى PostgreSQL أو مستودع تحليلي، واحفظ الاستجابات الأصلية في مخزن كائنات مع التاريخ والطلب في اسم الملف. ويُعد حفظ الأصل مفيداً على نحو خاص عند تحسين المحلّل، إذ يمكن تشغيله مجدداً على البيانات التاريخية من دون استدعاء واجهة API مرة أخرى.
جدولة عملية الجمع
لإنشاء أرشيف يومي، شغّل البرنامج النصي عبر cron أو أي مجدول آخر متاح في بيئتك. فمثلاً، يمكن لمهمة مجدولة تشغيل ملف Python مرة يومياً، مع تمرير المفتاح وعبارات البحث عبر متغيرات البيئة. تحقّق من طلب واحد أولاً، ثم من القائمة كاملة، وبعد ذلك فقط أضف الجدولة.
لضمان موثوقية التشغيل، احفظ حالة كل طلب، وحدّ عدد المحاولات عند وقوع أخطاء مؤقتة، وسجّل أن عملية الجمع غير مكتملة إذا تعذر تنفيذ طلب لإحدى العبارات. لا تُدرج المفتاح في رسائل الأخطاء. ومن المفيد أيضاً فصل الملفات بحسب التاريخ واسم الطلب حتى لا تستبدل إعادة التشغيل لقطة سابقة.
اختر وتيرة الجمع وفقاً للمهمة وحجم الطلبات. فلتقرير يومي، تكفي عملية تشغيل واحدة في اليوم؛ أما الجمع بوتيرة أعلى فيناسب الحالات التي يهم فيها الفريق رصد التغيرات خلال اليوم. ابدأ بقائمة صغيرة من العبارات، وتحقق من فائدة النتائج المعادة، ثم وسّع عملية الجمع ضمن شروط الوصول وقواعد استخدام البيانات.
استخدم الذكاء الاصطناعي للتجميع حسب الموضوع
بعد تأكيد مخطط الاستجابة، يمكن تمرير حقول نصية مختارة إلى نموذج لتجميع الأوصاف ضمن موضوعات محددة مسبقاً أو إعداد مسودة موجزة للملخص. احتفظ بجانب التصنيف بمعرّف المنشور الأصلي وعبارة البحث ومقتطف النص الذي استندت إليه الفئة. وبهذا يستطيع المحلل الانتقال من استنتاج النموذج إلى السجل الأصلي.
احسب الفروق العددية والترتيب وإزالة التكرار باستخدام شيفرة عادية. فالنموذج ملائم لمعالجة النص وصياغة التقرير، أما العدّادات والطوابع الزمنية فاستخرجها من الاستجابات المحفوظة. ويساعد الفصل بين هذه العمليات على توضيح مصدر كل استنتاج.
تحقّق يدوياً من عينة من الفئات الآلية واحفظ التصحيحات كأمثلة اختبار. وإذا جُمعت أنواع مختلفة من المنشورات باستمرار ضمن فئة واحدة، فحسّن تعريفات الفئات وأعد التحقق. وتساعد هذه العملية على تقييم جودة التصنيف على بيانات مهمتك.
الخلاصة: أرشيف قابل للتكرار وملخص قابل للتحقق
بعد تشغيل الطلب الموثق مع المعامل keyword، يصبح لدى الفريق أرشيف يوضح العبارات التي شُغّلت، ومتى حدث ذلك، والبيانات التي أعادتها واجهة API لكل عبارة. ويمكن الاستناد إليه لإنشاء جدول للنتائج ومقارنة الحقول المؤكدة بين اللقطات وإعداد قائمة بالمنشورات التي عُثر عليها لتحليلها يدوياً.
ابدأ بطلب تجريبي واحد، ثم اضبط قائمة العبارات والجدولة. يورد وصف TikTok Scraper API العنوان الأساسي وخريطة المسارات؛ وتوضح مواصفات API معاملات /searchVideo وبنية الاستجابة. ويشكّل أرشفة الاستجابات التي جرى التحقق منها أساساً لتحليلات قابلة للتكرار باستخدام عبارات بحث ثابتة.