是該努力點了!
951 字
5 分鐘
Chrome DevTools Protocol

Chrome DevTools Protocol#

簡介#

Chrome DevTools Protocol (CDP) 是一個由 Chrome 開發的協議,用於與瀏覽器進行通信,
以便控制瀏覽器行為,檢查瀏覽器狀態,以及調試網頁應用程序。
CDP 通常用於自動化測試、網頁性能分析、網頁爬蟲等等…
簡單說就是: 打開一個Chrome實例;像一個 server,並且可以透過 ws 去將這個 browser 進行可程式化的控制。

啟動 chrome 使用遠端除錯:#

相關手冊連結#

chrome 本身提供一些 argv 可以使用,如上述連結所示
透過這個列表可以設定 chrome 啟動時使用的參數:包含最大化(--start-maximized)、關閉GPU加速(--disable-gpu)、開啟除錯模式(--remote-debug-port)等等…
這邊使用 --remote-debugging-port 來開啟遠端除錯模式,目前常見的 CDP 相關工具預設是 9222 port 口。

通常放置位置:#

  • Windows: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
  • MacOS: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome
  • Linux: /usr/bin/google-chrome

在 cmd 或是 terminal 中輸入以下指令:#

# 請自行更換系統之可執行檔案
#   - Windows: `chrome.exe`
#   - Mac: `Google\ Chrome`
#   - Linux: `google-chrome`
# 如有不同請自行搜索安裝路徑。
./Google\ Chrome --remote-debugging-port=9222 --remote-allow-origin='*'

小小嘗試(使用 Http Endpoints 進行操作):#

注意: 運行這個例子的時候,需要先將 browser 開啟,並且是有開啟 remote-debugging-port 的狀態。

  • 相關訪問路徑 cdp-url-endpoints
    • http://localhost:9222/json : 可以看到目前開啟的頁面列表
    • http://localhost:9222/json/list : 可以看到目前開啟的頁面列表(等效)
    [
        {
            description: "",
            devtoolsFrontendUrl: "/devtools/inspector.html?ws=localhost:9222/devtools/page/6D2BD5C1755253A158A5DA5493FF8F38",
            id: "6D2BD5C1755253A158A5DA5493FF8F38",
            title: "新分頁",
            type: "page",
            url: "chrome://newtab/",
            webSocketDebuggerUrl: "ws://localhost:9222/devtools/page/6D2BD5C1755253A158A5DA5493FF8F38"
        },
        {
            description: "",
            devtoolsFrontendUrl: "/devtools/inspector.html?ws=localhost:9222/devtools/page/352AB7903FBC103E6E01802D93D8F62F",
            id: "352AB7903FBC103E6E01802D93D8F62F",
            parentId: "6D2BD5C1755253A158A5DA5493FF8F38",
            title: "chrome-untrusted://new-tab-page/one-google-bar?paramsencoded=",
            type: "iframe",
            url: "chrome-untrusted://new-tab-page/one-google-bar?paramsencoded=",
            webSocketDebuggerUrl: "ws://localhost:9222/devtools/page/352AB7903FBC103E6E01802D93D8F62F"
       }
    ]
    • http://localhost:9222/json/version : 可以看到 chrome 版本資訊
    {
        Browser: "Chrome/128.0.6613.120",
        Protocol-Version: "1.3",
        User-Agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 >Safari/537.36",
        V8-Version: "12.8.374.26",
        WebKit-Version: "537.36 (@095705ac6d469e273c0fe064494a53a561381fc8)",
        webSocketDebuggerUrl: "ws://localhost:9222/devtools/browser/22dfda32-3003-4672-be1b-45d27c07dad6" // 這個是 chrome 的 >websocket url
    }
    • http://localhost:9222/json/activate/{pageId} : 可以切換頁面(激活頁面)
    curl http://localhost:9222/json/activate/6D2BD5C1755253A158A5DA5493FF8F38
    • http://localhost:9222/json/close/{pageId} : 可以關閉頁面
    curl http://localhost:9222/json/close/6D2BD5C1755253A158A5DA5493FF8F38
    • http://localhost:9222/json/new : 可以開啟新頁面
    curl -X PUT http://localhost:9222/json/new\?https://claude.ai/

    上述指令的相關回應如下:#

    {
        "description": "",
        "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/682859C585BB8A3BC69D1E96C0DBE730",
        "id": "682859C585BB8A3BC69D1E96C0DBE730",
        "title": "",
        "type": "page",
        "url": "https://claude.ai/",
        "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/682859C585BB8A3BC69D1E96C0DBE730"
    }

    透過 list 或是上述的資料中,可以看到有一個 devtoolsFrontendUrl 的路徑,可以透過這個路徑進行除錯#

    使用外部 browser 進行網頁打開,如同上述的 /json/new 來舉例,可以看到他的 devtoolsFrontendUrl/devtools/inspector.html?>ws=localhost:9222/devtools/page/682859C585BB8A3BC69D1E96C0DBE730
    所以你在外部 browser(如 edge, firefox 或是其他的瀏覽器開啟。) http://localhost:9222/devtools/inspector.html?ws=localhost:9222/devtools/page/682859C585BB8A3BC69D1E96C0DBE730 這樣子,就可以看到對應的畫面,可以對該頁面進行除錯。

小小嘗試(使用 Puppeteer 進行網頁操作):#

注意: 運行這個例子的時候,需要先將 browser 開啟,並且是有開啟 remote-debugging-port 的狀態。
這邊以我下面例子來說明;我安裝的是 puppeteer-core,這個套件是不包含 chrome 的,所以需要自行安裝 chrome 或是 chromium。

mkdir puppeteer-ws-test; cd puppeteer-ws-test;
npm init -y

npm i puppeteer-core
touch index.cjs

index.cjs#

const puppeteer = require('puppeteer-core');

(async () => {
    const browser = await puppeteer.connect({ // 連接到已經開啟的實例。
        browserWSEndpoint: `ws://localhost:9222/devtools/browser/22dfda32-3003-4672-be1b-45d27c07dad6`
        // browserWSEndpoint 在 /json/version 中可以看到。
    });
    
    const page = await browser.newPage(); // 開一個分頁
    await page.goto('https://example.com'); // 前往該網址
    await page.screenshot({ path: 'example.png' }); // 截圖(檔案名稱 example.png)
    await browser.close(); // 關閉瀏覽器
})();

執行 js#

node index.cjs

結果:#

  • 會在當前目錄下產生一個 example.png 的檔案,內容是 https://example.com 的截圖。

結論:#

在一些有趣的網站介紹中,多多少少可以看到類似像用程式控制瀏覽器進行自動化的行爲
像是 seleniumpuppeteerplaywright 等等…
而這些工具有部分的實踐方式就是透過 CDP 進行控制,因此才去找相關的資訊進行拓展知識的學習~
這邊只是簡單的介紹,如果有興趣可以去看看相關的文件,或是進行更深入的學習。