דלג לתוכן הראשי

סקריפטים מותאמים אישית

הסקריפטים המובנים מכסים את התהליכים הנפוצים. כשאתם צריכים משהו שהם לא נותנים — שלב בסדר אחר, מסך שהם לא נוגעים בו, או אפליקציה שאינה TikTok או Instagram — אפשר לכתוב זאת בעצמכם בכל שפה, ו-TikMatrix ימסור לכם את הטלפון.

דרישות

דרישת רישיון

סקריפטים מותאמים אישית דורשים מנוי Pro, Team או Business. למנוי Starter אין גישה.

מספר המכשירים במנוי שלכם הוא גם מגבלת המקביליות: מנוי Pro (20 מכשירים) יכול להפעיל 20 טלפונים בו-זמנית, בין אם דרך משימות מובנות, סקריפטים מותאמים אישית, או שילוב של השניים.

שתי דרכים להריץ סקריפט

עצמאי

אתם מריצים את התוכנית בעצמכם. TikMatrix רק משאיל לכם מכשירים.

from tikmatrix import TikMatrix

client = TikMatrix()

for device in client.devices():
if device["busy"]:
continue
with client.device(device["serial"], label="my crawler") as d:
d.press("home")
print(d.info())

מתאים למשימות חד-פעמיות, איסוף נתונים, וכל דבר שתרצו להפעיל מהמתזמן שלכם.

מנוהל

אתם רושמים את התוכנית ב-TikMatrix והיא הופכת למשימה ככל משימה אחרת. היא מקבלת את תור המשימות, מקביליות לפי המנוי, ניסיונות חוזרים אוטומטיים, יומן המשימות ותבניות תזמון. TikMatrix שוכר את המכשיר לפני הפעלת התוכנית שלכם ומעביר את מזהה השכירות דרך משתני הסביבה.

from tikmatrix import TikMatrix

with TikMatrix.from_env() as d: # המכשיר כבר שכור
d.click(text="Log in")
print("done") # השורה הזו תגיע ליומן המשימה

מתאים לכל דבר שתרצו להריץ שוב ושוב, לפי לוח זמנים, או על מכשירים רבים.

במה לבחור

עצמאימנוהל
מי מפעילאתםתור המשימות של TikMatrix
שכירת מכשיראתם משיגים אותהכבר מוחזקת בעת ההפעלה
ניסיונות חוזרים, תזמון, יומןאתם בוניםכלול
הרצה על מכשירים רביםאתם כותבים את הלולאהמשימה אחת לכל מכשיר, במקביל
הכי מתאים לחקירה, זחלנים, משימות חד-פעמיותכל דבר שתרצו לחזור עליו

אפשר להתחיל במצב עצמאי בזמן שמלטשים את התהליך, ואז לרשום את אותו קובץ כסקריפט מנוהל — השורה היחידה שמשתנה היא TikMatrix.from_env().

תחילת עבודה

1. התקינו את ספריית הלקוח

pip install requests

לאחר מכן העתיקו את tikmatrix.py מספריית ה-SDK לצד הסקריפט שלכם. הספרייה היא קובץ יחיד ללא תלויות נוספות.

אינכם חייבים להשתמש בה — הממשק הוא JSON רגיל מעל HTTP, ונקודות הקצה הגולמיות מתועדות למטה.

2. כתבו את הסקריפט

from tikmatrix import TikMatrix

client = TikMatrix()
with client.device("192.168.1.5:5555") as d:
d.press("home")
d.adb("shell", "am", "start", "-a", "android.settings.SETTINGS")
d.wait_for(text="Settings", timeout=15)
d.screenshot("settings.png")

הריצו אותו כש-TikMatrix פתוח והטלפון מחובר. אם הוא מדפיס מילון עם פרטי המכשיר — הכול מחובר כמו שצריך.

3. רשמו אותו (מצב מנוהל בלבד)

עברו אל מכשירים ← סקריפטים מותאמים אישית ← הוספת סקריפט:

שדהמשמעות
שםמוצג ברשימת הסקריפטים וביומן המשימות
פקודהשורת התוכנית שתורץ, למשל python C:/scripts/my_flow.py
תיקיית עבודהאופציונלי. היכן התוכנית מתחילה
פלטפורמהראו מצבי פלטפורמה למטה
פסק זמןכמה שניות עד שהסקריפט ייעצר והמשימה תסומן ככושלת. ברירת מחדל 1800
משתני סביבה נוספיםאובייקט JSON אופציונלי שנמזג לסביבת התוכנית
מופעללכבות סקריפט בלי למחוק אותו. סקריפט מכובה אינו ניתן לשליחה

לאחר מכן לחצו ▶ בשורת הסקריפט ובחרו מכשירים, בדיוק כמו בסקריפט מובנה.

תנו לעוזר לכתוב אותו

העוזר החכם יכול לנסח סקריפט מותאם אישית מתיאור בשפה רגילה ולרשום אותו בצעד אחד. הוא מציג לכם את הקובץ כולו לפני שנכתב משהו לדיסק.

שכירות מכשירים

טלפון יכול להיות מופעל רק על ידי דבר אחד בכל רגע. שכירתו מודיעה ל-TikMatrix שהמכשיר תפוס, ולכן:

  • תור המשימות לא ישלח משימה לאותו מסך, ו
  • קריאות ה-JSON-RPC שלכם מדווחות על תקינות הסוכן בדיוק כפי שסקריפט מובנה עושה, כך שמנגנון הפיקוח רואה סוכן עסוק ולא סוכן אילם.

שכירות גם תופסת מקום מכשיר אחד מהמנוי שלכם.

לשכירויות יש תפוגה — 120 שניות כברירת מחדל, 600 לכל היותר. ספריית פייתון מחדשת את שלכם בתהליכון רקע ומשחררת אותה בסיום בלוק ה-with, כך שסקריפט שקורס משחרר את המכשיר תוך שניות במקום להחזיק בו עד שתפעילו מחדש את היישום. אם אתם קוראים לממשק ישירות, עליכם לשלוח פעימות לב בעצמכם.

אפשר לראות כל שכירות פעילה — ולשחרר אותה בכפייה — תחת הגדרות ← Developer API ← הפעלות מכשיר פעילות.

מצבי פלטפורמה

סקריפט רשום מצהיר על היעד שלו:

Generic — המכשיר נמסר כמות שהוא. אף אפליקציה לא נפתחת, אין החלפת חשבונות, אין בדיקת שיטת קלט, ולא נסגר דבר בסיום. השתמשו בזה כדי להפוך לאוטומטי כל דבר שאינו TikTok או Instagram.

TikTok / Instagram — האפליקציה נפתחת והחשבון מוחלף לפני שהתוכנית שלכם מתחילה, והאפליקציה נסגרת בסיום, בדיוק כמו בסקריפט מובנה. TIKMATRIX_PACKAGE מציין איזו חבילה נבחרה. השתמשו בזה כדי להוסיף שלב שהסקריפטים המובנים אינם מכסים.

משתני סביבה

סקריפט מנוהל מקבל:

משתנהמשמעות
TIKMATRIX_API_BASEכתובת השרת, למשל http://127.0.0.1:50809
TIKMATRIX_SESSION_IDהשכירות שכבר מוחזקת עבורכם
TIKMATRIX_SERIALהמכשיר שאליו נשלחה המשימה
TIKMATRIX_PACKAGEחבילת האפליקציה שנבחרה
TIKMATRIX_PLATFORMtiktok, instagram או generic

TikMatrix.from_env() קורא את כל אלה עבורכם.

סקריפטים עצמאיים אינם מקבלים אף אחד מהם — שכרו מכשיר במפורש במקום זאת.

כל מה שתכניסו למשתני סביבה נוספים נמזג מעליהם, וזו הדרך הרגילה לתת לאותו סקריפט רשום הגדרות שונות בכל הרצה בלי לערוך את הקובץ.

מדריך ספריית פייתון

TikMatrix — החיבור

קריאהמה היא עושה
TikMatrix(base_url=None, timeout=30.0)מתחבר. נסוג ל-TIKMATRIX_API_BASE ואז ל-http://127.0.0.1:50809
client.devices()מכשירים מחוברים, כל אחד עם serial, real_serial ו-busy
client.sessions()כל השכירויות הפעילות, כולל כאלה שאינן של תהליך זה
client.device(serial, label=..., ttl_secs=120)שוכר מכשיר ומחזיר Device
TikMatrix.from_env()מאמץ את המכשיר שאיתו הופעל סקריפט מנוהל

Device — הטלפון

קריאהמה היא עושה
d.info()פרטי מכשיר מ-UIAutomator2
d.window_size()(רוחב, גובה)
d.screenshot(path=None)בייטים של PNG, ואפשר לכתוב אותם ל-path
d.hierarchy()עץ הממשק הנוכחי כ-XML
d.find(text=, resource_id=, description=, class_name=)צמתים תואמים, כל אחד עם bounds ו-center
d.exists(**criteria)האם יש התאמה כלשהי
d.wait_for(timeout=10.0, interval=1.0, **criteria)ממתין עד להופעה ואז מחזיר
d.click(timeout=10.0, **criteria)ממתין לרכיב ואז מקיש במרכזו
d.click_xy(x, y)מקיש בנקודת ציון
d.swipe(sx, sy, ex, ey, steps=20)מחליק
d.press(key)back, home, recent, enter, …
d.input_text(text)מקליד בשדה שבמיקוד דרך שיטת הקלט המהירה המצורפת
d.jsonrpc(method, params=None, timeout=10)כל שיטה של UIAutomator2
d.adb(*args, timeout_ms=None)מריץ פקודת ADB
d.release()משחרר את השכירות. with עושה זאת עבורכם

find מתאים מול עץ הממשק שנשלף, ולכן כשבורר מחטיא אפשר להריץ print(d.hierarchy()) ולראות בדיוק במה הוא חיפש. בוחן הרכיבים בתצוגת המכשיר מציג את אותו עץ באופן חזותי, וזו בדרך כלל הדרך המהירה ביותר למצוא resource-id.

input_text דורש ADB

הוא שולח שידור לשיטת הקלט המצורפת, וזה עובר דרך adb shell. הפעילו גישת ADB לפני השימוש, אחרת תקבלו שגיאת 403.

שגיאות

הספרייה זורקת שני חריגים, שניהם תת-מחלקות של RuntimeError:

חריגמתי
DeviceBusyErrorHTTP 409 — המכשיר כבר שכור, או שאין מקום מכשיר פנוי במנוי
TikMatrixErrorכל השאר: מנוי נמוך מדי, שכירות שפגה, ADB מכובה, בורר שמעולם לא התאים
from tikmatrix import TikMatrix, TikMatrixError, DeviceBusyError

client = TikMatrix()
try:
with client.device("192.168.1.5:5555") as d:
d.click(text="Log in", timeout=20)
except DeviceBusyError:
print("הטלפון הזה תפוס אצל מישהו אחר — נסו אחר")
except TikMatrixError as exc:
print("נכשל:", exc)

בסקריפט מנוהל, לתת לחריג לצאת החוצה הוא בדרך כלל הדבר הנכון: קוד יציאה שאינו אפס מסמן את המשימה ככושלת, ועקבות השגיאה מגיעים ליומן המשימה.

נקודות קצה HTTP

פעולות מכשיר דורשות כותרת x-session-id המצביעה על שכירות פעילה. אין מפתח API: כמו שאר הממשק המקומי, נקודות הקצה האלה אינן מאומתות — היכולת להגיע למחשב ברשת היא בקרת הגישה. הן אינן שולחות כותרות CORS, ולכן קראו להן מתוך תוכנית (curl, פייתון, כל קוד צד-שרת) ולא מדף בדפדפן.

שיטהנתיבמטרה
GET/api/v1/rpc/devicesמציג מכשירים מחוברים והאם כל אחד תפוס
POST/api/v1/rpc/sessionשוכר מכשיר ← session_id
POST/api/v1/rpc/session/{id}/heartbeatמאריך את השכירות
DELETE/api/v1/rpc/session/{id}משחרר את השכירות
GET/api/v1/rpc/sessionמציג שכירויות פעילות
POST/api/v1/rpc/jsonrpcקורא לשיטת UIAutomator2
POST/api/v1/rpc/adbמריץ פקודת ADB
GET/api/v1/rpc/hierarchy?serial=עץ הממשק הנוכחי כ-XML
GET/api/v1/rpc/screenshot?serial=המסך הנוכחי כ-PNG

תשובות JSON משתמשות באותה מעטפת כמו שאר הממשק המקומי — {"code": 0, "message": "success", "data": ...}, כאשר code שונה מאפס בכישלון. hierarchy ו-screenshot מחזירים את הגוף הגולמי.

דוגמה

# שכירת מכשיר
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session \
-H "Content-Type: application/json" \
-d '{"serial":"192.168.1.5:5555","label":"curl test","ttl_secs":120}'

# {"code":0,"message":"success","data":{"session_id":"ff3ae079-...","serial":"192.168.1.5:5555", ...}}

# הפעלה
curl -X POST http://127.0.0.1:50809/api/v1/rpc/jsonrpc \
-H "x-session-id: ff3ae079-..." \
-H "Content-Type: application/json" \
-d '{"serial":"192.168.1.5:5555","method":"deviceInfo","params":[]}'

# שמירה על השכירות בזמן העבודה
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-.../heartbeat \
-H "Content-Type: application/json" \
-d '{"ttl_secs":120}'

# החזרת המכשיר
curl -X DELETE http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-...

שגיאות

מצבמשמעות
403מנוי נמוך מ-Pro, אין שכירות, שכירות שפגה, או גישת ADB מכובה
409המכשיר כבר שכור, או שאין מקום מכשיר פנוי במנוי

כתיבה בשפה אחרת

אין כאן שום דבר ייחודי לפייתון. כל סביבת ריצה שיודעת לשלוח בקשת HTTP מתאימה — החוזה של המצב המנוהל הוא רק "קרא שלושה משתני סביבה, וצא עם 0 בהצלחה".

// my_flow.js — רשמו עם: node C:/scripts/my_flow.js
const base = process.env.TIKMATRIX_API_BASE || "http://127.0.0.1:50809";
const serial = process.env.TIKMATRIX_SERIAL;
const session = process.env.TIKMATRIX_SESSION_ID;

async function jsonrpc(method, params = []) {
const res = await fetch(`${base}/api/v1/rpc/jsonrpc`, {
method: "POST",
headers: { "content-type": "application/json", "x-session-id": session },
body: JSON.stringify({ serial, method, params }),
});
const body = await res.json();
if (!res.ok || body.code !== 0) throw new Error(body.message || res.statusText);
return body.data;
}

console.log(await jsonrpc("deviceInfo"));

אם המפרש אינו ב-PATH, ציינו את הנתיב המלא בשדה פקודה, למשל C:/Program Files/nodejs/node.exe C:/scripts/my_flow.js.

הפעלת סקריפט מותאם אישית מהממשק

סקריפטים רשומים ניתנים להפעלה גם דרך ממשק ניהול המשימות, כך שסקריפט אחד יכול להכניס לתור עבודה נוספת:

curl -X POST http://127.0.0.1:50809/api/v1/task \
-H "Content-Type: application/json" \
-d '{
"serials": ["192.168.1.5:5555"],
"script_name": "custom_script",
"script_config": {
"custom_script_id": 1,
"custom_script_platform": "generic"
}
}'

custom_script_id הוא המזהה של הסקריפט שרשמתם.

גישת ADB

/api/v1/rpc/adb נותן לסקריפטים שלכם מעטפת על המכשיר — היא נחוצה להעלאת מדיה, התקנת APK ושינוי הגדרות מערכת. מכיוון שזו מעטפת מלאה על נקודת קצה ללא מפתח API, היא מגיעה מכובה. הפעילו אותה תחת הגדרות ← Developer API ← אפשר פקודות ADB כשיש לכם סקריפט שזקוק לה; אוטומציית ממשק דרך /rpc/jsonrpc עובדת גם בלעדיה.

כל עוד היא כבויה, /api/v1/rpc/adb מחזיר 403 ושאר הממשק ממשיך לעבוד. כל פקודת ADB שסקריפט מריץ נכתבת לקובץ היומן שלכם.

איך לכתוב סקריפטים שממשיכים לעבוד

  • המתינו למסך, אל תישנו במקומו. d.wait_for(...) חוזר ברגע שהרכיב מופיע; המתנה קבועה היא או איטית מהנדרש או קצרה מדי ביום פחות טוב.
  • בדקו לפני שאתם מקישים. d.exists(...) על חלון הסכמה או על הודעת "לא עכשיו" עולה שליפת עץ אחת ומציל הרצה שאחרת הייתה מקישה על ריק.
  • הדפיסו מה עשיתם. במצב מנוהל, stdout הוא יומן המשימה, והוא התיעוד היחיד של הרצה שאיש לא צפה בה.
  • הפכו הרצה חוזרת לבטוחה. ניסיון חוזר מריץ את התוכנית כולה מחדש, ולכן סקריפט שמפרסם צריך לבדוק אם כבר פרסם במקום להניח שהוא מתחיל מאפס.
  • סקריפט אחד למשימה אחת. המקביליות נספרת לכל מכשיר, ולכן עשר משימות קטנות על עשרה טלפונים מסתיימות הרבה לפני סקריפט אחד שרץ בלולאה על עשרה טלפונים.

הערות ומגבלות

  • הפקודה מורצת ישירות, לא דרך מעטפת, ולכן && ו-| נחשבים לארגומנטים ולא לאופרטורים. רשמו cmd /c "..." (Windows) או sh -c "..." (macOS) אם אתם רוצים התנהגות של מעטפת.
  • הקיפו במרכאות נתיבים שמכילים רווחים: "C:/Program Files/Python/python.exe" my_script.py.
  • סקריפט שחורג מפסק הזמן שלו נעצר והמשימה מסומנת ככושלת.
  • קוד יציאה שאינו אפס מסמן את המשימה ככושלת; כל מה שהסקריפט כותב ל-stdout ול-stderr מגיע ליומן המשימה.
  • סקריפטים רצים באותן הרשאות כמו TikMatrix עצמו. רשמו רק תוכניות שכתבתם בעצמכם או שאתם סומכים עליהן.

פתרון תקלות

API access requires Pro or higher plan (403) הרישיון במחשב הזה הוא Starter או אינו פעיל. בדקו בהגדרות ← רישיון.

החיבור נדחה בכתובת 127.0.0.1:50809 TikMatrix אינו פועל, או שהוא פועל תחת משתמש אחר. השרת קיים רק כל עוד היישום פתוח.

409 בכל ניסיון שכירות או שהטלפון באמת תפוס — הסתכלו בהגדרות ← Developer API ← הפעלות מכשיר פעילות — או שכל מקומות המכשירים במנוי כבר תפוסים על ידי משימות פעילות.

השכירות פגה באמצע שלב ארוך זמן החיים כברירת מחדל הוא 120 שניות והספרייה מחדשת אותו ברקע, ולכן זה בדרך כלל אומר שהסקריפט חסם את התהליכון הראשי שלו לזמן ארוך יותר. העלו את ttl_secs (עד 600), או הוציאו את העבודה הארוכה מאותו תהליכון.

d.adb(...) נכשל עם 403 גישת ADB מכובה. הפעילו אותה תחת הגדרות ← Developer API ← אפשר פקודות ADB.

בורר שאף פעם לא מתאים print(d.hierarchy()) מציג בדיוק את העץ שבו find חיפש. הטקסט מושווה בהתאמה מדויקת, ולכן רווח מיותר או תווית מתורגמת הם הסיבה השכיחה; התאמה לפי resource_id יציבה יותר מהתאמה לפי text.

המשימה מסומנת ככושלת אבל הטלפון נראה תקין קראו את יומן המשימה. קוד יציאה שאינו אפס — כולל חריג שלא נתפס בסוף הרצה מוצלחת — מכשיל את המשימה גם אם האוטומציה עצמה עבדה.

הצעדים הבאים