Quay lại blog

Ba thế hệ tự động hóa trình duyệt: mô phỏng đầu vào, điều khiển bằng giao thức và quyết định của mô hình

Tự động hóa trình duyệt đã trải qua ba thế hệ. Mỗi thế hệ giải quyết nút thắt của thế hệ trước nhưng đồng thời đẩy nút thắt tiếp theo sang một vị trí khác. Hiểu vấn đề còn tồn tại của từng thế hệ hữu ích hơn việc ghi nhớ tên công cụ.

Tự động hóa trình duyệt đã tồn tại hơn hai mươi năm và trải qua ba hướng phát triển chính. Điều đáng chú ý là mỗi thế hệ giải quyết một loại vấn đề khác nhau, và sau khi giải quyết xong, nút thắt lại được đẩy sang một vị trí mới.

浏览器自动化三代路线:输入模拟、协议驱动与模型决策的关键步骤与判断维度示意图

Thế hệ thứ nhất: giả lập một người đang di chuyển chuột ở cấp hệ điều hành

Những hình thức tự động hóa đầu tiên thực ra không hoạt động bên trong trình duyệt mà ở cấp hệ điều hành. Script di chuyển chuột và nhấn phím, còn trình duyệt chỉ thụ động nhận các đầu vào đó.

Ưu điểm là tính phổ quát: bất cứ thứ gì xuất hiện trên màn hình đều có thể được thao tác, từ trang web, ứng dụng client đến phần mềm desktop cũ, và trình duyệt không cần mở bất kỳ giao diện nào. Đổi lại, nhược điểm cũng rất rõ. Script dựa vào tọa độ màn hình, nên chỉ cần thay đổi độ phân giải, tỷ lệ hiển thị của hệ thống hoặc vị trí cửa sổ là cùng một thao tác có thể bấm lệch. Nó cũng không biết trang đã tải xong hay chưa nên chỉ có thể dựa vào thời gian chờ cố định. Việc chạy song song còn khó hơn: một máy chỉ có một bộ chuột và bàn phím, nên mười môi trường cần mười máy.

Vấn đề mà thế hệ này để lại rất đơn giản: nó không nhìn thấy trang.

Thế hệ thứ hai: bỏ qua màn hình và giao tiếp trực tiếp với trình duyệt

Sự xuất hiện của WebDriver đã đưa tự động hóa từ cấp pixel lên cấp phần tử: thay vì tìm vị trí pixel thứ 800 trên màn hình, hệ thống tìm một phần tử cụ thể trong trang. Cùng một đoạn mã có thể điều khiển nhiều trình duyệt khác nhau và được viết bằng nhiều ngôn ngữ, cũng là lý do nó trở thành tiêu chuẩn trong lĩnh vực kiểm thử.

Sau đó, các giải pháp dựa trên giao thức gỡ lỗi của trình duyệt đã phát triển hướng đi này sâu hơn. Puppeteer và Playwright giao tiếp trực tiếp với engine và có thể lấy trạng thái bên trong của trang: tự động chờ phần tử sẵn sàng, chặn và sửa request, kết nối tới một phiên bản trình duyệt đang mở, chạy headless và mở nhiều context song song. Phần lớn các khả năng mà ngày nay được xem là hiển nhiên đã được hoàn thiện ở giai đoạn này.

Thế hệ này giải quyết vấn đề điều khiển và độ ổn định nhưng vẫn để lại hai điểm khác. Thứ nhất, script vẫn được con người viết cứng. Khi cấu trúc trang thay đổi hoặc selector không còn hiệu lực, phải quay lại sửa mã, khiến chi phí bảo trì tăng theo quy mô dự án. Thứ hai là vấn đề mang tính nền tảng hơn: nó quản lý cách thao tác chứ không quản lý việc chủ thể thao tác trông giống ai. Kết nối trực tiếp qua giao thức giúp điều khiển chính xác hơn, nhưng dấu vết của tự động hóa không biến mất chỉ vì thay đổi cách giao tiếp. Một script dù chạy rất ổn vẫn có thể bị nhìn nhận là script.

Thế hệ thứ ba: con người không còn viết từng bước và vấn đề lại chuyển chỗ

Thay đổi của thế hệ thứ ba không nằm ở cách điều khiển mà ở cách ra quyết định. Hai thế hệ đầu đều yêu cầu con người mô tả rõ từng bước: bấm nút nào, điền trường nào và theo thứ tự nào. Đến thế hệ dựa trên mô hình, bạn đưa ra mục tiêu, mô hình tự lập kế hoạch đường đi và vẫn có thể tìm lại lối vào khi giao diện được thiết kế lại.

Vì vậy, những rắc rối vụn vặt trước đây như viết selector thế nào hay chờ bao lâu dần bớt nghiêm trọng. Nhưng các vấn đề mới xuất hiện ngay lập tức.

Điểm mấu chốt là bản thân mô hình không truy cập trang web. Trình duyệt vẫn là thành phần thực sự mở trang, tải tài nguyên và duy trì trạng thái đăng nhập. Vì thế, khi tác vụ bắt đầu thiếu ổn định, nguyên nhân thường không phải mô hình quyết định sai mà nằm ở môi trường thực thi bên dưới: nhiều tác vụ dùng chung một trình duyệt và làm lẫn cookie cùng cache; đặc điểm fingerprint quá giống nhau khiến nền tảng xem các tác vụ đều đến từ cùng một máy; tài khoản bị dùng chéo giữa các tác vụ nên một bất thường có thể kéo theo nhiều tác vụ khác; môi trường cần được tạo tạm thời rồi thu hồi sau khi dùng nhưng lại thiếu cơ chế điều phối thống nhất. Mô hình giải quyết câu hỏi làm thế nào và biến câu hỏi làm ở đâu thành nút thắt mới.

Lớp bổ sung trong kiến trúc

Khi đặt ba thế hệ cạnh nhau, khác biệt không đơn giản là thế hệ nào tiên tiến hơn. Mỗi thế hệ phải tiếp nhận những gì thế hệ trước chưa xử lý được. Ở hai thế hệ đầu, môi trường không phải vấn đề lớn vì thao tác diễn ra trên trình duyệt của chính máy bạn. Đến giai đoạn Agent, tác vụ chạy theo lô, đồng thời và không có người giám sát, nên môi trường phải được quản lý rõ ràng: mỗi tác vụ chạy trong một môi trường độc lập, fingerprint và session không bị dùng lẫn; trạng thái đăng nhập được giữ qua các tác vụ để không phải đăng nhập lại mỗi lần; IP, múi giờ và ngôn ngữ được ghép đồng bộ; môi trường được tạo và thu hồi theo nhu cầu như tài nguyên tính toán.

PurpleMark hoạt động chính ở lớp này, biến môi trường trình duyệt thành tài nguyên có thể điều phối để Agent tập trung vào logic tác vụ.

Nhờ vậy, việc lựa chọn cũng dễ xác định hơn. Hệ thống kiểm thử doanh nghiệp và tài sản script hiện có có thể tiếp tục theo hướng cũ; ứng dụng web phức tạp cần kiểm soát ở cấp request phù hợp với thế hệ dựa trên giao thức; còn với các tác vụ do mô hình lập kế hoạch và phải chạy ổn định lâu dài, công nghệ của hai thế hệ đầu vẫn dùng được nhưng lớp môi trường cần được giải quyết riêng. Nếu tình huống của bạn yêu cầu thao tác trông giống như do một người dùng thật thực hiện, đó không phải điều mà riêng framework tự động hóa có thể cung cấp, bất kể thuộc thế hệ nào.

Ngoài lộ trình kỹ thuật còn có một ranh giới khác: thao tác tự động phải tuân thủ quy định của nền tảng đích và pháp luật địa phương. Việc chạy được về mặt kỹ thuật không đồng nghĩa với việc phù hợp về mặt kinh doanh.