feat: add automation scripts, XML parsing logic for UI element identification, and supplementary asset images

This commit is contained in:
Victor Phan
2026-07-21 09:56:12 +07:00
parent 749a30735e
commit 97ddcd2699
8 changed files with 109 additions and 89 deletions
+82 -63
View File
@@ -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)}"