Chuyển đến nội dung

Extension Chrome

Nạp các extension (tiện ích mở rộng) dạng unpacked khi khởi chạy bằng extensions. Cả Manifest V2 và V3 đều chạy được, ở cả chế độ có giao diện (headed) lẫn headless, trên Windows và Linux.

Nạp một extension

Truyền một danh sách thư mục extension dạng unpacked — mỗi thư mục chứa một manifest.json — vào launch(), launch_persistent_context() hoặc serve() (.NET: Extensions = new[] { ... }). Extension được nạp vào profile của trình duyệt, nên chỉ có các kiểu khởi chạy incognito là không dùng được (ephemeral_profile=False, launch() của async API, .NET LaunchAsync). Extension dành cho các trình duyệt bạn khởi chạy bằng SDK; trình duyệt được lưu trữ sẵn (hosted) không nạp extension.

python
from clearcote import launch_persistent_context

ctx = launch_persistent_context(
    "./profile",
    extensions=["./ext/ublock", "./ext/my-helper"],   # unpacked directories
)
page = ctx.pages[0] if ctx.pages else ctx.new_page()
page.goto("https://example.com")
javascript
import { launchPersistentContext } from "clearcote";

const ctx = await launchPersistentContext("./profile", {
  extensions: ["./ext/ublock", "./ext/my-helper"],
});

SDK tự đặt cả --load-extension lẫn --disable-extensions-except cho bạn. Việc đi kèm thành cặp này rất quan trọng: nếu đứng một mình, --load-extension sẽ bị bỏ qua khi chạy automation — đó thường là lý do một extension âm thầm không xuất hiện.

Lấy thư mục unpacked

Clearcote nạp thư mục, không nạp file .crx. File .crx là một file ZIP có thêm header chữ ký, nên chỉ cần giải nén là bạn có một thư mục nạp được:

bash
unzip extension.crx -d ./ext/extension

Clearcote không thể cài đặt hay cập nhật extension từ Chrome Web Store — các patch quyền riêng tư của upstream đã gỡ bỏ phần tích hợp đó. Hãy đóng gói thư mục unpacked cùng với automation của bạn và tự cập nhật nó: extension nạp theo cách này không bao giờ tự cập nhật. Playwright và Puppeteer cũng dùng đúng mô hình này.

Manifest V2 vẫn hoạt động

Chrome gốc không còn chạy extension Manifest V2 nữa. Clearcote thì vẫn chạy, vì bộ patch quyền riêng tư của upstream đã khôi phục khả năng này — nhờ vậy các content blocker chỉ hỗ trợ MV2 và các công cụ nội bộ cũ vẫn tiếp tục chạy được ở đây, dù đã ngừng hoạt động trên Chrome.

python
# both of these load and run
ctx = launch_persistent_context("./profile", extensions=["./ext/mv2-tool", "./ext/mv3-tool"])

Headless

Extension nạp được ở chế độ headless cũng như headed. Không cần thêm flag, và cũng không cần chạy display server chỉ để extension hoạt động.

python
ctx = launch_persistent_context("./profile", extensions=["./ext/my-helper"], headless=True)

Lưu ý về fingerprint

Extension là code của bạn chạy trong profile của bạn, và Clearcote không che giấu nó. Từ đó dẫn tới hai điều, và cả hai đều nên được quyết định có chủ đích ngay từ đầu thay vì để sau này mới phát hiện ra.

  • Extension có thể bị quan sát. Một content script viết lại DOM, inject style hoặc chặn request sẽ làm thay đổi những gì trang đo được. Một site so sánh markup của chính nó với những gì nó đã gửi đi có thể biết được có thứ gì đó đã sửa trang. Điều này đúng với mọi trình duyệt có extension và không phải tín hiệu riêng của Clearcote, nhưng nó vẫn là một tín hiệu.
  • Web-accessible resources có thể bị dò. Nếu một extension khai báo web_accessible_resources, bất kỳ trang nào cũng có thể thử fetch chrome-extension://<id>/<file> và biết được extension đó đang có mặt. Nên ưu tiên các extension không khai báo gì, và cân nhắc use_dynamic_url cho những extension buộc phải khai báo.

Nếu mục tiêu của bạn là chặn request chứ không phải cung cấp UI, hãy cân nhắc làm việc đó ở tầng automation bằng CDP Network.setBlockedURLs — nó chặn theo pattern URL, không thêm bề mặt extension nào và vẫn giữ cache của trình duyệt (page.route() của Playwright cũng dùng được nhưng sẽ tắt cache). Xem Cấu hình khuyến nghị để nắm nguyên tắc chung: chỉ spoof những gì cần, và chỉ thêm bề mặt khi nó thực sự xứng đáng.

Xử lý sự cố

  • Không có gì xảy ra. Kiểm tra xem đường dẫn có trỏ đúng tới thư mục chứa manifest.json không, chứ không phải thư mục cha của nó hay một file .crx.
  • Content script không bao giờ chạy. Xác nhận rằng pattern matches bao phủ URL bạn đang truy cập — http://localhost/* không khớp với http://127.0.0.1:8080/.
  • Chạy được ở headed nhưng không chạy ở headless. Điều này không nên xảy ra trên bản build này; cả hai đều hoạt động. Nếu bạn gặp trường hợp này, vui lòng mở một issue kèm theo manifest.