import gradio as gr import datetime import json import re import pycountry from curl_cffi import requests from lxml import html # --- كلاس TikTokUser (يبقى كما هو) --- class TikTokUser: def __init__(self, data) -> None: user = data.get("user", {}) stats = data.get("stats", {}) self.username = user.get("uniqueId", "N/A") self.name = user.get("nickname", "N/A") self.avatar = user.get("avatarMedium", "") self.bio = user.get("signature", "لا توجد سيرة ذاتية.") self.created = user.get("createTime", None) self.verified = user.get("verified", False) self.private = user.get("privateAccount", False) self.country_code = user.get("region", "N/A") self.language_code = user.get("language", "N/A") self.followers = stats.get("followerCount", 0) self.following = stats.get("followingCount", 0) self.hearts = stats.get("heart", 0) self.video_count = stats.get("videoCount", 0) self.friends = stats.get("friendCount", 0) if self.created: try: self.created = datetime.datetime.fromtimestamp(self.created).strftime('%Y-%m-%d %H:%M:%S') except (TypeError, ValueError): self.created = "غير معروف" else: self.created = "غير معروف" self.country = "غير معروف" if self.country_code != "N/A": try: self.country = pycountry.countries.get(alpha_2=self.country_code.upper()).name except AttributeError: self.country = f"رمز ({self.country_code})" self.language = "غير معروف" if self.language_code != "N/A": try: self.language = pycountry.languages.get(alpha_2=self.language_code.lower()).name except AttributeError: self.language = f"رمز ({self.language_code})" if bio_link := user.get("bioLink", {}): if link_url := bio_link.get("link"): self.bio += f"\n\n🔗 رابط السيرة الذاتية: {link_url}" self.followers_formatted = f"{self.followers:,}" self.following_formatted = f"{self.following:,}" self.hearts_formatted = f"{self.hearts:,}" self.video_count_formatted = f"{self.video_count:,}" self.friends_formatted = f"{self.friends:,}" # --- دالة get_user_info (تبقى كما هي، مع تعديل بسيط للتعامل مع الأخطاء لـ Gradio) --- def get_user_info_from_tiktok(username): username = re.sub(r"^.*@", "", username).strip() if not username: return "خطأ: اسم المستخدم لا يمكن أن يكون فارغاً." url = f"https://www.tiktok.com/@{username}" print(f"محاولة جلب البيانات من: {url}") try: r = requests.get(url, impersonate="chrome", timeout=15) r.raise_for_status() tree = html.fromstring(r.text, parser=html.HTMLParser(encoding="utf8")) script_tag = tree.xpath('//script[@id="__UNIVERSAL_DATA_FOR_REHYDRATION__"]') if not script_tag: return ("خطأ: لم يتم العثور على وسم البيانات في الصفحة. " "قد يكون هيكل الصفحة قد تغير، أو تم حظر الطلب.") data = json.loads(script_tag[0].text) user_info_data = data.get("__DEFAULT_SCOPE__", {})\ .get("webapp.user-detail", {})\ .get("userInfo") if not user_info_data: return (f"خطأ: لم يتم العثور على معلومات لمستخدم تيك توك: '{username}'. " "تأكد من صحة اسم المستخدم وأنه حساب عام.") user = TikTokUser(user_info_data) # تنسيق المخرجات لـ Gradio output_html = f"""
صورة الملف الشخصي

{user.name} {"✅ (موثق)" if user.verified else ""} {"🔒 (خاص)" if user.private else ""}

{user.username}

{user.followers_formatted} متابع
{user.following_formatted} يتابع
{user.hearts_formatted} إعجاب
{user.video_count_formatted} فيديو

السيرة الذاتية:

{user.bio}

معلومات إضافية:

الدولة: {user.country}

اللغة: {user.language}

تاريخ الإنشاء: {user.created}

⚠️ ملاحظة هامة: هذا التطبيق يقوم بمحاولة استخلاص البيانات مباشرة من صفحة تيك توك. هذه الطريقة غير رسمية وقد تتوقف عن العمل في أي وقت بسبب تغييرات تيك توك. كما أنها قد تتعارض مع شروط خدمة تيك توك، وتؤدي إلى حظر عنوان IP الخاص بك. استخدم على مسؤوليتك الخاصة ولأغراض تعليمية فقط.

""" return output_html except Exception as e: return f"حدث خطأ: {str(e)}. يرجى المحاولة مرة أخرى باسم مستخدم صحيح وتأكد من أن الحساب عام." # --- واجهة Gradio --- iface = gr.Interface( fn=get_user_info_from_tiktok, # الدالة التي ستقوم بالعمل inputs=gr.Textbox(label="أدخل اسم مستخدم تيك توك (بدون @)", placeholder="مثال: cristiano"), # مدخل نصي outputs=gr.HTML(label="معلومات مستخدم تيك توك"), # مخرج HTML لعرض المعلومات المنسقة title="جالب معلومات مستخدم تيك توك (تجريبي)", description="قم بإدخال اسم مستخدم تيك توك لمحاولة جلب معلوماته. هذه الطريقة تعتمد على الاستخلاص وقد تفشل.", theme="soft", # يمكنك تغيير الثيم allow_flagging="never" # لا يسمح بوضع علامات على النتائج ) if __name__ == "__main__": iface.launch() # local_host=True # share=True # لإنشاء رابط مشاركة مؤقت إذا كنت تختبر محلياً