Keywords
puppeteer review, web scraping, open source, benchmark
Content
Puppeteer là thư viện Node của Google dùng để điều khiển một Chrome thật bằng JavaScript — bạn viết phần tự động hóa, Chrome DevTools Protocol sẽ mang lệnh đi, và một trình duyệt đầy đủ sẽ render trang trước khi bạn đọc bất kỳ byte nào. Dự án nằm tại puppeteer/puppeteer trên GitHub: giấy phép Apache-2.0, viết bằng TypeScript, và có khoảng 95,3k sao (95.307 sao vào ngày tôi chụp dữ liệu). Cách định vị chính thức của nó cũng khá rõ ràng — "một JavaScript API để điều khiển Chrome (và thử nghiệm Firefox)" — câu này cho bạn biết nó là gì, và cũng nói rất rõ điều nó không phải.
Tôi đã chạy Puppeteer 24.16.0 qua cùng một máy chủ fixture và các demo công khai mà chúng tôi dùng cho mọi thư viện tự động hóa trình duyệt: một danh mục tĩnh có phân trang, một bài viết, một danh mục render bằng JavaScript, một JSON API, một route trả về 500, một đồ thị crawl nhỏ, cùng Books to Scrape và Quotes to Scrape. Nó render sạch sẽ, gọn gàng, không ồn ào. Nhưng nó cũng để lại đúng một việc trên bàn tôi — cũng là việc mà mọi thư viện headless browser đều để lại — và thành thật về khoảng trống đó gần như là điểm phân biệt quan trọng nhất giữa một bài đánh giá hữu ích và một bản thông cáo báo chí.
Có một con số nổi bật hơn cả các chỉ số recall. Trên một trang mà dữ liệu được trả về từ một JSON endpoint, Puppeteer lấy được đủ 8 bản ghi mà không cần scrape DOM — nó chạy fetch ngay trong trang và đọc trực tiếp đối tượng response. Điều đó, cộng với khả năng render tự nhiên và chụp screenshot hoạt động ổn, chính là hình dạng thật của công cụ này: một bộ render Chrome trưởng thành, không phải một framework crawl; và sự khác biệt đó rất quan trọng trước khi bạn gõ một dòng code nào.
Thực chất Puppeteer là gì, và nó cạnh tranh với ai
Nhãn danh mục ở đây có tác dụng thật, nên hãy bắt đầu từ đó. Puppeteer là một thư viện tự động hóa trình duyệt. Nó khởi chạy Chrome, mở trang, cho JavaScript của trang chạy, rồi đưa cho bạn kết quả đã render để đọc hoặc chụp ảnh. Đó là lý do duy nhất để bạn chọn nó thay vì một HTTP client cộng với HTML parser: bạn muốn xem trang sau khi script chạy xong, chứ không phải lớp vỏ rỗng mà server gửi ban đầu.
Về mặt bản chất, nó cạnh tranh với các thư viện dùng trình duyệt thật khác — Playwright và Selenium — chứ không phải với các framework crawl như Scrapy hay các công cụ chuyển sang Markdown cho LLM. Nếu bạn ném vào Puppeteer một nghìn URL rồi mong nó tự xếp hàng, khử trùng lặp, giới hạn tốc độ lịch sự, và ghi dữ liệu thành dataset, thì bạn đang mang một bộ render đi giải bài toán crawl. Nó sẽ render từng trang rất đẹp, nhưng không quản lý phần điều phối. (Đó là giới hạn phạm vi, không phải lỗi — tôi sẽ quay lại điểm này, vì đây là điều quan trọng nhất cần hiểu trước khi chọn công cụ.)

Puppeteer sinh ra từ đội Chrome của Google, nên nó ưu tiên Chrome ngay từ thiết kế và API của nó giống như một lớp găng tay mỏng, vừa khít, phủ lên chính giao thức gỡ lỗi của trình duyệt. Nó đủ lâu đời để trở nên "chán" theo nghĩa tốt: những phương thức bạn cần đã ổn định nhiều năm, tài liệu đầy đủ, và hệ sinh thái xung quanh cũng rất sâu.
Render tự nhiên và kiểu lấy dữ liệu bằng fetch ngay trong trang
Có hai hành vi đáng tách ra từ bảng kết quả vì chúng quyết định cách bạn thực sự dùng công cụ này.
Trước hết là render tự nhiên. Danh mục render bằng JavaScript — một trang xây lưới sản phẩm ở phía client sau khi tải xong — trả về 8/8, kèm một ảnh chụp toàn trang được lưu xuống đĩa. Phần thiết lập rất tối giản nhưng có chờ nội dung mục tiêu sau goto. Trang JS của Quotes to Scrape công khai cũng trả về đủ mười câu trích dẫn với cùng một cách làm. Đây là kết quả trên fixture, không phải điểm recall render mang tính tổng quát.
Thứ hai, fixture JSON API tải sản phẩm từ /api/dynamic-products. Chạy fetch cùng origin thông qua page.evaluate trả về đủ tám bản ghi mà không cần parse các hàng đã render. Đây là một mẫu đánh giá browser thông dụng, không phải phát hiện riêng của Puppeteer. Nó có thể giúp việc trích xuất trở nên đơn giản hơn khi endpoint và hợp đồng request đã biết; nhưng header xác thực, token lúc chạy, chính sách credentials, CORS/CSP, service worker và phân trang vẫn có thể làm cho request của ứng dụng khác với kỳ vọng.
Điều thứ ba cần mang theo là cách nhìn nhận, chứ không phải một con số: Puppeteer là một Chrome renderer trưởng thành, và nó không phải crawler. Cả hai vế đều đúng, và vế thứ hai chính là phần nhiều bài viết bỏ qua.
Puppeteer giao tiếp với Chrome như thế nào

Trên Chrome, Puppeteer dùng Chrome DevTools Protocol (CDP), kênh JSON-over-WebSocket mà DevTools của trình duyệt sử dụng. puppeteer.launch() khởi chạy Chrome và mở kết nối giao thức này; các lệnh như goto, $$eval, và screenshot bọc các thao tác trình duyệt qua một API cấp cao hơn. Hỗ trợ Firefox đi theo đường WebDriver BiDi được mô tả bên dưới, nên không phải mọi thao tác của Puppeteer đều là lệnh CDP thuần túy.
page.evaluate chạy một hàm trong ngữ cảnh của trang, nên một fetch('/api/...') tương đối sẽ dùng origin của trang đó và có thể tái sử dụng cookie và trạng thái phiên hợp lệ. Nó không tự động tái tạo các header xác thực do ứng dụng tạo ra, tùy chọn request, token hay hành vi của service worker. Trên fixture same-origin này, nó trả JSON trực tiếp; còn request trong môi trường production thì phải kiểm tra đúng hợp đồng thực tế của nó.
Nó cũng lý giải vì sao Puppeteer nặng. Mỗi trang là một tab trình duyệt thật với engine render thật nằm phía sau. Điều đó đổi lấy độ chính xác trên những trang nặng JavaScript, nhưng cũng tốn memory và thời gian khởi động hơn so với fetch chỉ dùng HTTP. Không có render miễn phí; CDP chỉ khiến hóa đơn trở nên dễ nhìn hơn.
Câu chuyện về engine, nói thẳng luôn
Có một cách nói tắt khá phổ biến là Puppeteer "chỉ dành cho Chrome." Với phiên bản tôi thử, điều đó không còn đúng, và sửa lại nhận định này sẽ làm thay đổi cách so sánh.
| Engine | Puppeteer 24.16.0 điều khiển như thế nào | Có được kiểm tra trong các test này không |
|---|---|---|
| Chrome | Ưu tiên Chrome qua CDP — mặc định, nên các automation hiện có vẫn chạy | có |
| Firefox | Có hỗ trợ được ghi tài liệu thông qua WebDriver BiDi kể từ v23 | không |
| WebKit | Không được điều khiển | — |
Cả Chrome for Developers và Mozilla đều công bố việc hỗ trợ Firefox khi tính năng này ra mắt. Bản build tôi chạy, 24.16.0, đã qua xa mốc v23, nên nói "chỉ Chrome" là đánh giá thấp những gì thực sự có trong hộp. Việc thiếu WebKit, cộng với câu chuyện đa engine còn trẻ hơn Playwright, mới là khác biệt về độ rộng hỗ trợ — chứ không phải "một engine so với ba".
Đường Firefox/BiDi đã được tài liệu hóa và có trong bản tôi thử, nhưng tôi không chạy fixture của mình qua nó, nên tôi đang báo cáo một khả năng, không phải một phép đo. Nếu Firefox là yếu tố sống còn với mục tiêu của bạn, hãy kiểm tra trực tiếp trên các trang của chính bạn trước khi chốt. Với độc giả muốn xem so kè đầy đủ về engine và ngôn ngữ, bài so sánh Playwright-vs-Puppeteer của chúng tôi chạy cả hai thư viện qua cùng bộ test này và khép lại câu hỏi "nên chọn cái nào" ở đó; ở đây, chủ đề chỉ là Puppeteer.
Thực tế cài đặt: phần nặng nhất là trình duyệt
Đường dẫn mặc định npm install puppeteer sẽ tải xuống một bản Chrome for Testing tương thích. Hành vi này có thể được tắt hoặc chuyển hướng bằng cấu hình, và người dùng có thể trỏ Puppeteer sang một executable khác, nên việc khớp phiên bản sẽ phụ thuộc vào lựa chọn triển khai. Phần tải browser là phần nặng nhất của lần cài này; ảnh chụp kiểm tra bằng package manager không được xem là một thuộc tính an toàn bền vững.
Việc đóng gói tự động đó vừa là lợi thế trải nghiệm thật sự, vừa là cái giá về dung lượng thật sự, và đáng để gọi rõ cả hai mặt. Lợi thế: bạn không phải đi tìm một trình duyệt tương thích hay khóa phiên bản thủ công; npm install cho bạn một cặp chạy được ngay. Cái giá: bạn đang tải cả một trình duyệt, nên phải tính trước dung lượng đĩa và băng thông, nhất là trong CI nơi cache lạnh sẽ trả cái giá đó ở mỗi runner mới.
Nó cũng là một điểm khác biệt rõ ràng so với Playwright, nơi hai bước được tách ra — bạn cài thư viện trước, rồi chạy thêm npx playwright install để tải các bản browser. Cách nào cũng không quá đau; chỉ là thất bại theo những kiểu khác nhau. Một lệnh duy nhất của Puppeteer có thể làm bạn bất ngờ vì kích thước khi mạng có giới hạn, còn bước thứ hai của Playwright có thể bị quên mất. Hãy biết mình đang đi theo đường nào.
Kết quả thực chiến

Mọi test đều chạy trên một local fixture server tại 127.0.0.1 cộng với hai website demo công khai, trên Node v22.22.3, macOS arm64, với Puppeteer 24.16.0 và Chrome đi kèm. Ground truth cho từng fixture đã được ghi lại trước khi chạy, nên recall được đo so với một tập kỳ vọng cố định chứ không phải thứ Puppeteer tình cờ in ra.
Bộ nghiên cứu công khai bao gồm fixture server, test runner, và ground truth. Lock dependency và bản tóm tắt chạy thô được cố tình loại khỏi gói công bố vì quá trình rà soát bảo mật nghiêm ngặt đã từ chối dữ liệu lockfile và material endpoint phụ thuộc vào môi trường. Để tái tạo fixture local an toàn, hãy chạy npm install rồi node run_puppeteer_material_tests.mjs trong tools/puppeteer/tests, sau đó đối chiếu kết quả với ground truth đã công bố. Các trang demo công khai có thể thay đổi, nên fixture local là nền ổn định nhất cho các kiểm tra số lượng kỳ vọng.
Nếu muốn tái dựng lịch sử phụ thuộc chính xác, hãy tạo và kiểm tra một lockfile mới ngay tại máy của bạn thay vì coi một lockfile không công bố là bằng chứng công khai.
| Test | Mục tiêu | Kết quả |
|---|---|---|
| Danh mục tĩnh + phân trang | local fixture | 12/12, recall 1.0 |
| Trích xuất bài viết | local fixture | title + 3/3 đoạn văn, tách được boilerplate |
| Trang JS động (render tự nhiên) | local fixture | 8/8, recall 1.0, đã lưu screenshot toàn trang |
JSON API động (fetch trong trang) | local fixture | 8/8, recall 1.0, không scrape DOM |
| Xử lý HTTP 500 | local fixture | status 500 có thể kiểm tra, không ném lỗi |
| Crawl graph (BFS viết tay) | local fixture | 12 trang, độ sâu {0:1, 1:4, 2:7} |
| Books to Scrape | demo công khai | 20 sản phẩm |
| Quotes JS | demo công khai | 10 trích dẫn, render tự nhiên |
Một vài mục trong số này đáng nói thêm một câu ngoài bảng.
Phần code phân trang do chúng tôi viết đã lấy lại đủ 12 mục danh mục như mong đợi. Bộ selector cho bài viết lấy được title và ba đoạn nội dung dự kiến; phần boilerplate xung quanh vẫn còn trong DOM. Puppeteer cung cấp DOM đã render, còn logic selector — chứ không phải Puppeteer tự nó — quyết định cái gì được tính là nội dung bài viết.
Trên route HTTP 500 đã thử, goto trả về một response object với status 500 có thể kiểm tra và không ném lỗi. Điều đó không nói gì về timeout, lỗi DNS, crash trình duyệt, frame bị tách, hay các lỗi điều hướng khác — những thứ đó vẫn cần xử lý rõ ràng.
Đồ thị crawl là phần nói lên toàn bộ câu chuyện. Đi qua các link nội bộ của fixture để đến 12 trang, đồng thời theo dõi độ sâu để không ghé lại URL cũ, cần một breadth-first search viết tay — vì Puppeteer không có hàng đợi crawl tích hợp sẵn. Nó tìm được đủ 12 trang ở các độ sâu {0:1, 1:4, 2:7}, nghĩa là BFS của tôi hoạt động. Nhưng BFS là của tôi. Puppeteer render từng trang; logic đi từng trang của website là code tôi tự viết. Với 12 trang thì chỉ là một chục dòng code và không có gì to tát. Với hàng nghìn URL, kèm khử trùng lặp, retry và độ trễ lịch sự, một chục dòng đó sẽ biến thành cả một dự án.
Có một lưu ý tôi sẽ nhắc lại vì nó rất dễ bị lạm dụng: các artifact có thời gian chạy cho từng test, nhưng đó chỉ là quan sát một lần, trên một máy, không phải benchmark. Tôi không xếp hạng tốc độ Puppeteer so với công cụ khác chỉ từ một chiếc laptop và một lần chạy. Những con số ở đây chỉ hỗ trợ việc đánh giá recall và hành vi trên tám kiểu trang khác nhau — không phải một tuyên bố về tốc độ.
Những gì tôi không test
Để tránh đọc kết quả vượt quá phạm vi của chúng, dưới đây là những thứ nằm ngoài lần chạy test, và vì vậy cũng nằm ngoài các con số này:
| Ngoài phạm vi test | Trạng thái |
|---|---|
| Firefox qua WebDriver BiDi | Có tài liệu, có sẵn trong 24.16.0, nhưng không được chạy ở đây |
| Proxy và chặn request | Chưa test; cả hai đều là tính năng được hỗ trợ nhưng tôi không chạy |
| Khả năng chạy song song ở quy mô lớn | Tôi chỉ chạy ở quy mô nhỏ; hành vi của browser fleet dưới concurrency thực tế chưa được đo |
| Chạy lại trên bản mới nhất | Tôi đã test 24.16.0; npm latest là 25.3.0, cao hơn một major version, tính đến 2026-07-09. Các API tôi dùng (launch, goto, $$eval, screenshot, fetch trong trang) vẫn ổn định từ 24 sang 25, nhưng cách an toàn là chạy lại trên 25.3.0 trước khi đặt niềm tin vào các con số chính xác |
Không mục nào trong số này là điểm trừ. Chúng chỉ là ranh giới của những gì một lần chạy fixture có thể trung thực tuyên bố.
Ưu và nhược điểm
Ưu điểm:
- Render JavaScript tự nhiên, có chờ nội dung rõ ràng: 8/8 trên fixture động và đủ mười quote trên demo công khai, kèm screenshot.
- Bộ selector cho phân trang và bài viết lấy lại đúng các mục kỳ vọng của fixture.
fetchtrong trang trả về đủ tám bản ghi từ endpoint same-origin đã biết mà không cần parse DOM.- Route HTTP 500 đã test trả về response có thể kiểm tra mà không phát sinh exception.
- Cài đặt mặc định tải xuống một bản Chrome for Testing tương thích; vẫn có thể dùng executable khác hoặc bỏ qua bước tải.
- API trưởng thành, ưu tiên Chrome qua CDP, tài liệu đầy đủ, hệ sinh thái sâu. Giấy phép Apache-2.0.
- Rộng hơn danh tiếng của nó: đã có hỗ trợ Firefox qua WebDriver BiDi từ v23.
Nhược điểm:
- Không có hàng đợi crawl tích hợp, không có writer cho dataset, không có throttle — bài toán crawl quy mô lớn cần code của bạn hoặc một wrapper.
- Không có engine WebKit, và câu chuyện đa engine còn trẻ hơn Playwright.
- Nặng như một trình duyệt thật: phải tải Chrome đi kèm và tốn bộ nhớ cho từng trang so với công cụ chỉ dùng HTTP.
- Dựa trên Node; nếu muốn dùng từ ngôn ngữ khác, bạn phải tự xây và duy trì một lớp cầu nối.
- Phiên bản tôi chạy (24.16.0) còn sau bản latest trên npm (25.3.0) một major version — hãy kiểm tra lại trên bản hiện tại trước khi tin vào số liệu chính xác.
Phù hợp với ai, và ai nên bỏ qua
Hãy chọn Puppeteer nếu bạn làm việc trong Node, mục tiêu của bạn hiển thị tốt trên Chrome (đa số đều vậy), và bạn muốn một thư viện trưởng thành, tập trung, biến "trang sau khi JavaScript chạy" thành thứ bạn có thể đọc và chụp ảnh. Với việc scrape một tập trang động, hoặc lấy một JSON API bằng chính session của trang, hoặc chụp screenshot đã render làm bằng chứng, nó là lựa chọn mặc định mạnh và ít phiền phức. Tùy chọn Firefox qua BiDi có sẵn nếu nhu cầu của bạn mở rộng hơn, và hệ sinh thái của nó có nghĩa là đa số vấn đề bạn gặp đều đã có người gặp trước.
Hãy nghĩ kỹ nếu bài toán của bạn là điều phối crawl chứ không phải render. Nếu bạn cần đi qua hàng trăm hay hàng nghìn URL với khử trùng lặp, retry và rate limit, bản thân Puppeteer sẽ khiến bạn phải tự dựng crawler bằng tay — đó không phải độ cao phù hợp với nó. Cũng nên bỏ qua headless browser hoàn toàn nếu trang của bạn không thật sự cần JavaScript để lộ dữ liệu; khi một HTTP request và parser đã trả về nội dung, dùng trình duyệt thật là quá nặng, chỉ làm tốn memory và thời gian thiết lập. Và nếu bạn cần độ tương thích WebKit hoặc một client không dùng JavaScript, đây không phải công cụ phù hợp cho trục đó.
Các lựa chọn thay thế, và Thunderbit nằm ở đâu
Cách nhìn trung thực trước tiên: Puppeteer là miễn phí, Apache-2.0, tự lưu trữ, và bạn phải tự chịu mọi phần khi vận hành nó — cụm trình duyệt, code crawl bạn gắn thêm, và cuộc chiến chống bot kéo dài. Với nhiều dự án, việc tự chủ như vậy là hoàn toàn đúng, và không có dịch vụ quản lý nào render một trang được phép truy cập rẻ hơn một browser bạn đã có sẵn.
Trong thế giới mã nguồn mở, cách so sánh hữu ích là theo công việc, không theo logo. Nếu xét riêng ở quy mô crawl, Crawlee là người bạn đồng hành tự nhiên: PuppeteerCrawler của nó bọc Puppeteer bằng request queue, dataset và throttling mà thư viện này cố ý không cung cấp, nên bạn giữ phần render nhưng có thêm lớp điều phối. Nếu đầu ra bạn cần là Markdown sạch cho pipeline LLM thay vì DOM đã render, Crawl4AI sẽ điều khiển một trình duyệt thật và tạo đúng thứ đó. Nếu trang của bạn không cần browser, một framework ưu tiên HTTP như Scrapy là một nhóm công cụ khác, nhẹ hơn. Khi phải cân nhắc nhiều lựa chọn cùng lúc, bài tổng quan open-source scraper của chúng tôi sẽ đặt các nhóm này cạnh nhau.
Một dịch vụ quản lý như Thunderbit sẽ đưa vận hành trình duyệt và trích xuất ra sau một API. Nó không được chạy qua bộ fixture của Puppeteer này, nên bài đánh giá không đưa ra bất kỳ kết luận ghép đôi nào về render, chặn, chất lượng trích xuất hay chi phí. Ranh giới quyết định ở đây là quyền sở hữu vận hành: bạn tự bảo trì browser và code crawl, hay trả cho một nhà cung cấp để vận hành một phần lớp đó.
Với Puppeteer, bạn không mất phí sử dụng của nhà cung cấp, nhưng compute, băng thông, bảo trì trình duyệt, điều phối và vận hành đều là của bạn. Một hướng quản lý sẽ tính phí theo mức dùng và chuyển bớt trách nhiệm đó sang nhà cung cấp. Thí nghiệm này không so sánh kết quả giữa hai bên.
Dùng thử Thunderbit để trích xuất dữ liệu web
Kết luận
Puppeteer 24.16.0 đáng để cân nhắc nếu bạn làm việc trong Node và cần tự động hóa trình duyệt ưu tiên Chrome. Code fixture do chúng tôi viết đã lấy lại 12 mục tĩnh, 8 mục động và 10 quote từ demo công khai; API same-origin đã biết trả về 8 bản ghi qua page.evaluate; screenshot hoạt động; và route HTTP 500 đã test vẫn có thể kiểm tra. Những kết quả này thuộc về các fixture đã nêu và một major version cũ hơn, không phải là khả năng recall trích xuất nói chung.
Tuy vậy, hãy đặt kỳ vọng cho đúng. Puppeteer là một bộ render, không phải crawler: cú đi qua 12 trang của tôi cần một BFS viết tay vì không có queue tích hợp, và ở quy mô lớn khoảng trống đó là công việc thực sự — hãy giao nó cho Crawlee hoặc tự xây cơ chế đó. Nó ưu tiên Chrome, có hỗ trợ Firefox qua BiDi nhưng không có WebKit, nên không phải công cụ cho độ rộng đa engine. Nó mang trọng lượng của một trình duyệt thật. Và tôi đã test 24.16.0 trong khi latest là 25.3.0, nên hãy chạy lại trên bản hiện tại trước khi tin vào các con số chính xác. Hiểu bốn điều đó ngay từ đầu, Puppeteer là một thư viện tự động hóa Chrome rất xuất sắc. Còn nếu bạn kỳ vọng nó tự crawl cả site cho bạn, thì bạn sẽ phải tự viết cái crawler mà bạn tưởng là mình đã tải về rồi.
Dùng thử Thunderbit để trích xuất dữ liệu web Get Started Free
Câu hỏi thường gặp
Puppeteer có render trang JavaScript không, hay tôi cần plugin?
Nó render tự nhiên, không cần plugin. Trên fixture động của tôi, nó trả về đủ 8/8 sản phẩm được dựng ở phía client với recall 1.0 và một screenshot toàn trang, còn trang JS của Quotes to Scrape công khai cũng trả đủ 10 quote theo cùng cách — chỉ cần goto, rồi đọc DOM đã render. Vì Puppeteer điều khiển một Chrome thật qua DevTools Protocol, script của trang thực sự được chạy trước khi bạn đọc bất cứ thứ gì.
Puppeteer có thể scrape JSON API mà không cần parse HTML không?
Có, khi endpoint và hợp đồng request cho phép. page.evaluate có thể gửi request từ origin của trang và có thể tái sử dụng cookie hợp lệ, nhưng nó không tự động tái tạo header, token, tùy chọn hay hành vi service worker do ứng dụng tạo ra. Trên fixture same-origin, nó trả về đủ tám bản ghi mà không cần parse DOM.
Puppeteer có phải là web crawler không?
Không — nó là thư viện tự động hóa trình duyệt, không phải framework crawl. Nó không có request queue, dataset writer hay throttle tích hợp, nên cú crawl 12 trang của tôi (độ sâu {0:1, 1:4, 2:7}) cần một breadth-first search viết tay. Đó là giới hạn phạm vi, không phải khuyết điểm. Nếu cần crawl quy mô lớn, hãy ghép nó với wrapper như PuppeteerCrawler của Crawlee, vốn thêm queue và cơ chế dataset mà Puppeteer không có.
Puppeteer chỉ dùng cho Chrome thôi à?
Không còn đúng nữa. Nó ưu tiên Chrome qua CDP, nhưng từ v23 đã có hỗ trợ Firefox được tài liệu hóa qua WebDriver BiDi, và phiên bản tôi test (24.16.0) đã vượt xa mốc đó. Điều nó không điều khiển là WebKit, và câu chuyện đa engine của nó còn trẻ hơn Playwright — đó mới là hạn chế chính xác, chứ không phải "chỉ Chrome." Ở đây tôi chỉ chạy Chrome, nên phần Firefox qua BiDi tôi chỉ báo cáo như một khả năng được tài liệu hóa, không phải là thứ tôi đo trực tiếp.
Cài Puppeteer thực sự tải xuống cái gì?
Mặc định, npm install puppeteer sẽ tải một bản Chrome for Testing tương thích. Việc tải này có thể được bỏ qua hoặc chuyển hướng, và bạn cũng có thể cấu hình một executable khác, nên việc khớp phiên bản sẽ phụ thuộc vào cách triển khai. Hãy dự trù dung lượng đĩa và băng thông cho trình duyệt, nhất là trên các runner CI chưa có cache. Bài đánh giá này test 24.16.0; hãy chạy lại các fixture cốt lõi trên bản release hiện tại tại thời điểm công bố.


