diff --git a/serverPython/QuyTrinh/1784602240883_8694694984948253645_8694694984948253645_9c2042e1be9ada518e1110f1e207089e.jpg b/serverPython/QuyTrinh/1784602240883_8694694984948253645_8694694984948253645_9c2042e1be9ada518e1110f1e207089e.jpg new file mode 100644 index 0000000..33101df Binary files /dev/null and b/serverPython/QuyTrinh/1784602240883_8694694984948253645_8694694984948253645_9c2042e1be9ada518e1110f1e207089e.jpg differ diff --git a/serverPython/QuyTrinh/1784602240910_8694694984948253645_8694694984948253645_7735e91db922108a0227a08008af6eab.jpg b/serverPython/QuyTrinh/1784602240910_8694694984948253645_8694694984948253645_7735e91db922108a0227a08008af6eab.jpg new file mode 100644 index 0000000..ab0144e Binary files /dev/null and b/serverPython/QuyTrinh/1784602240910_8694694984948253645_8694694984948253645_7735e91db922108a0227a08008af6eab.jpg differ diff --git a/serverPython/QuyTrinh/1784602240954_8694694984948253645_8694694984948253645_e2e54338aa4d63f3714b138771e8142b.jpg b/serverPython/QuyTrinh/1784602240954_8694694984948253645_8694694984948253645_e2e54338aa4d63f3714b138771e8142b.jpg new file mode 100644 index 0000000..7fca4cc Binary files /dev/null and b/serverPython/QuyTrinh/1784602240954_8694694984948253645_8694694984948253645_e2e54338aa4d63f3714b138771e8142b.jpg differ diff --git a/serverPython/QuyTrinh/1784602240987_8694694984948253645_8694694984948253645_d297d8693af242dbd5182edc1b367a60.jpg b/serverPython/QuyTrinh/1784602240987_8694694984948253645_8694694984948253645_d297d8693af242dbd5182edc1b367a60.jpg new file mode 100644 index 0000000..5e5100a Binary files /dev/null and b/serverPython/QuyTrinh/1784602240987_8694694984948253645_8694694984948253645_d297d8693af242dbd5182edc1b367a60.jpg differ diff --git a/serverPython/QuyTrinh/1784602241014_8694694984948253645_8694694984948253645_329de251d9493b0049bbf99df54e6c2b.jpg b/serverPython/QuyTrinh/1784602241014_8694694984948253645_8694694984948253645_329de251d9493b0049bbf99df54e6c2b.jpg new file mode 100644 index 0000000..294b864 Binary files /dev/null and b/serverPython/QuyTrinh/1784602241014_8694694984948253645_8694694984948253645_329de251d9493b0049bbf99df54e6c2b.jpg differ diff --git a/serverPython/automation.py b/serverPython/automation.py index 7fbc368..88fafb6 100644 --- a/serverPython/automation.py +++ b/serverPython/automation.py @@ -1,75 +1,94 @@ import uiautomator2 as u2 import time -import logging - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) +import re class ShopeeBot: - def __init__(self, device_ip: str = ""): - """ - Khởi tạo kết nối qua Wireless Debugging - :param device_ip: IP và Port của điện thoại. Nếu để trống, u2 sẽ tự kết nối thiết bị mặc định - """ - self.device_ip = device_ip + def __init__(self, device_ip: str): + print(f"Đang kết nối tới thiết bị {device_ip}...") + self.d = u2.connect(device_ip) + print("Kết nối thành công!") + + def get_commission_rate(self, url: str) -> str: try: - if self.device_ip: - logger.info(f"Đang kết nối tới thiết bị {self.device_ip}...") - self.d = u2.connect(self.device_ip) - else: - logger.info("Đang tự động dò tìm thiết bị ADB đang kết nối...") - self.d = u2.connect() - - logger.info(f"Kết nối thành công: {self.d.info}") - except Exception as e: - logger.error(f"Lỗi kết nối ADB: {e}") - raise - - def get_commission(self, product_link: str) -> str: - """ - Mở Shopee, dán link và lấy phần trăm hoa hồng - """ - # 1. Khởi động app Shopee - logger.info("Mở ứng dụng Shopee...") - self.d.app_start("com.shopee.vn") - time.sleep(3) # Đợi app load, có thể tuỳ chỉnh - - # 2. Bấm vào thanh tìm kiếm (Ví dụ thao tác cơ bản) - logger.info("Tìm thanh tìm kiếm...") - # Ở đây tôi dùng textContains, bạn cần dùng công cụ Weditor để điều chỉnh lại theo đúng giao diện - search_box = self.d(textContains="Tìm kiếm", className="android.widget.TextView") - if search_box.exists: - search_box.click() + # 1. Đảm bảo màn hình sáng + self.d.screen_on() + + # 2. Khởi động lại Shopee từ đầu để tránh lỗi luồng cũ + print("Khởi động Shopee...") + self.d.app_start("com.shopee.vn", stop=True) + time.sleep(6) # Chờ app khởi động hoàn toàn + + # Tắt popup quảng cáo nếu có (nhấn phím Back hoặc tìm nút Tắt) + # Dùng thử phím Back 1 lần nếu có popup che màn hình + self.d.press("back") time.sleep(1) - else: - logger.warning("Không tìm thấy thanh tìm kiếm ở trang hiện tại.") - # 3. Dán link và enter - logger.info("Đang dán link sản phẩm...") - # Ở màn hình nhập liệu, giả sử có một ô đang focus - try: - self.d(focused=True).set_text(product_link) - self.d.press("enter") - # Đợi Shopee load trang sản phẩm (mạng chậm cần chờ lâu hơn) - time.sleep(6) - except Exception as e: - logger.error(f"Lỗi dán link: {e}") + # 3. Chuyển sang tab "Tôi" + print("Vào tab Tôi...") + if self.d(text="Tôi").exists: + self.d(text="Tôi").click() + else: + return "Lỗi: Không tìm thấy tab 'Tôi'" + time.sleep(2) - # 4. Tìm và đọc text phần trăm hoa hồng - logger.info("Đang quét màn hình lấy hoa hồng...") - # LƯU Ý: Phần text/ID này phụ thuộc vào giao diện tài khoản Affiliate Shopee của bạn. - try: - # Ví dụ giả định Element chứa chữ hoa hồng: - commission_element = self.d(textContains="Hoa hồng") + # 4. Tìm và ấn "Shopee Tiếp Thị Liên Kết" + print("Tìm mục Shopee Tiếp Thị Liên Kết...") + # Cuộn xuống cho đến khi thấy chữ này + self.d(scrollable=True).scroll.to(textContains="Tiếp Thị Liên Kết") + + if self.d(textContains="Tiếp Thị Liên Kết").exists: + self.d(textContains="Tiếp Thị Liên Kết").click() + else: + return "Lỗi: Không tìm thấy mục Tiếp Thị Liên Kết" + + time.sleep(6) # Mục này có thể tải hơi lâu vì gọi API + + # 5. Ấn tab "Chuyển đổi" ở thanh menu dưới cùng + print("Vào tab Chuyển đổi...") + if self.d(text="Chuyển đổi").exists: + self.d(text="Chuyển đổi").click() + else: + return "Lỗi: Không tìm thấy tab Chuyển đổi" + time.sleep(2) + + # 6. Nhập link vào ô Text + print("Nhập link sản phẩm...") + # Nếu có nút "Xóa tất cả" link cũ thì xóa trước + if self.d(text="Xóa tất cả").exists: + self.d(text="Xóa tất cả").click() + time.sleep(0.5) + + # Tìm ô nhập liệu (thường là EditText) + edit_text = self.d(className="android.widget.EditText") + if edit_text.exists: + edit_text.set_text(url) + else: + return "Lỗi: Không tìm thấy ô nhập link" + time.sleep(1) + + # 7. Bấm nút Chuyển Đổi màu cam + print("Bấm nút Chuyển Đổi...") + if self.d(text="Chuyển Đổi").exists: + self.d(text="Chuyển Đổi").click() + else: + return "Lỗi: Không tìm thấy nút Chuyển Đổi" + + time.sleep(4) # Chờ Shopee convert link và hiện kết quả + + # 8. Lấy tỷ lệ hoa hồng + print("Đang đọc tỷ lệ hoa hồng...") + commission_element = self.d(textContains="Tỷ lệ hoa hồng") if commission_element.exists: - # Lấy tất cả text của element đó (ví dụ "Hoa hồng: 15%") - commission_text = commission_element.get_text() - logger.info(f"Lấy thành công: {commission_text}") - return commission_text + text_result = commission_element.get_text() + # Text có dạng "Tỷ lệ hoa hồng 10,5%" + return text_result else: - logger.error("Không tìm thấy thông tin hoa hồng trên màn hình.") - return "Không tìm thấy thông tin" + # Nếu không tìm thấy, dump UI ra để debug + xml_dump = self.d.dump_hierarchy() + with open("error_dump.xml", "w", encoding="utf-8") as f: + f.write(xml_dump) + return "Lỗi: Không thấy Tỷ lệ hoa hồng (Đã lưu error_dump.xml)" + except Exception as e: - logger.error(f"Lỗi khi đọc dữ liệu màn hình: {e}") - return "Lỗi quét dữ liệu" + return f"Lỗi không xác định: {str(e)}" diff --git a/serverPython/parse_xml.py b/serverPython/parse_xml.py new file mode 100644 index 0000000..ab1717b --- /dev/null +++ b/serverPython/parse_xml.py @@ -0,0 +1,11 @@ +import xml.etree.ElementTree as ET + +tree = ET.parse('ui_dump.xml') +for node in tree.iter(): + if node.attrib.get('clickable') == 'true' and node.attrib.get('package') == 'com.shopee.vn': + clazz = node.attrib.get('class', '') + res_id = node.attrib.get('resource-id', '') + text = node.attrib.get('text', '') + desc = node.attrib.get('content-desc', '') + bounds = node.attrib.get('bounds', '') + print(f"{clazz} | {res_id} | text:{text} | desc:{desc} | bounds:{bounds}") diff --git a/serverPython/test_shopee.py b/serverPython/test_shopee.py index fa3ed90..0f11b3f 100644 --- a/serverPython/test_shopee.py +++ b/serverPython/test_shopee.py @@ -1,28 +1,18 @@ -import uiautomator2 as u2 import time +from automation import ShopeeBot -# Kết nối điện thoại -d = u2.connect('10.160.138.2:5555') -link = "https://vn.shp.ee/tZVnqovi" - -print("Đang bật sáng màn hình...") -d.screen_on() -# d.unlock() # Bỏ comment dòng này nếu máy bạn có màn hình khóa vuốt (không mật khẩu) -time.sleep(1) - -print("🚀 Đang bắn lệnh ép Shopee mở thẳng sản phẩm...") -# Lệnh ADB này ép Android mở link trực tiếp bằng app Shopee -d.shell(f'am start -a android.intent.action.VIEW -d "{link}"') - -# Chờ 8 giây để app load xong hình ảnh và thông tin (mạng chậm thì tăng lên) -print("⏳ Đang đợi Shopee tải trang...") -time.sleep(8) - -print("🔍 Đang quét cấu trúc màn hình hiện tại...") -xml_dump = d.dump_hierarchy() - -# Xuất toàn bộ giao diện màn hình ra một file XML để chúng ta "soi" -with open("ui_dump.xml", "w", encoding="utf-8") as f: - f.write(xml_dump) - -print("✅ Đã xuất giao diện ra file 'ui_dump.xml'.") +if __name__ == "__main__": + # Thay thế bằng IP của điện thoại trong mạng (lấy từ lệnh adb devices) + DEVICE_IP = '10.160.138.2:5555' + + bot = ShopeeBot(DEVICE_IP) + + test_url = "https://vn.shp.ee/tZVnqovi" + print(f"\n[BẮT ĐẦU] Lấy hoa hồng cho link: {test_url}") + + # Đoạn này sẽ chạy đúng quy trình: Mở Shopee -> Tôi -> Tiếp Thị Liên Kết -> Chuyển Đổi + result = bot.get_commission_rate(test_url) + + print("\n===============================") + print(f"🎯 KẾT QUẢ: {result}") + print("===============================\n")