最近寫個指令碼用到 puppeteer,然後安裝 Chromium 出現一點問題,這裡記錄一下解決方案。
Puppeteer 自動安裝失敗
在 Puppeteer 安裝時會自動安裝 Chromium,然而卻總是報錯 502 導致下載失敗,直接下載可以下載,命令列 wget 也可以,猜測是因為 Puppeteer 開啟了新的 process 來安裝導致環境變數丟失,然後就玄學上網失敗了。
這會回頭看了看 Puppeteer 的安裝指令碼,好像可以使用 npm_config_https_proxy
等配置來玄學上網。
function overrideProxy() {
// Override current environment proxy settings with npm configuration, if any.
const NPM_HTTPS_PROXY = process.env['npm_config_https_proxy'] || process.env['npm_config_proxy'];
const NPM_HTTP_PROXY = process.env['npm_config_http_proxy'] || process.env['npm_config_proxy'];
const NPM_NO_PROXY = process.env['npm_config_no_proxy'];
if (NPM_HTTPS_PROXY) {
process.env['HTTPS_PROXY'] = NPM_HTTPS_PROXY;
}
if (NPM_HTTP_PROXY) {
process.env['HTTP_PROXY'] = NPM_HTTP_PROXY;
}
if (NPM_NO_PROXY) {
process.env['NO_PROXY'] = NPM_NO_PROXY;
}
}
不過當時沒看就直接打算手動安裝 Chromium 了,要手動安裝在安裝 Puppeteer 時需要先關閉自動下載:
PUPPETEER_SKIP_DOWNLOAD='true' pnpm add puppeteer
這樣就可以跳過 Puppeteer 中自動的 Chromium 安裝。
手動安裝 Chromium
失敗嘗試
手動安裝首先是使用了 homebrew 的方式,但是由於之前玩 Stable Diffusion 一些依賴包的相容問題,我的 homebrew 切到了 x86 版本,所以安裝後的是 intel 晶片版本的 Chromium,導致無法開啟,開啟就會顯示彈窗:
You can’t open the application “Chromium” because this application is not supported on this Mac.
無奈就去官網: https://download-chromium.appspot.com/ 手動下載,結果不成想官網掛的也是 intel 版本:
不死心的下載試了一下,果然不行。
成功安裝
然後無奈的搜了一下,發現了這個問題: https://stackoverflow.com/questions/66002337/is-the-homebrew-chromium-m1-optimised ,其中提及到 homebrew 中安裝的指令碼:
arch = Hardware::CPU.intel? ? "Mac" : "Mac_Arm"
...
url "https://commondatastorage.googleapis.com/chromium-browser-snapshots/#{arch}/#{version}/chrome-mac.zip
原來只需要將地址中的架構型別變更更換為想要的版本就可以了。
而官網對應的下載地址是: https://download-chromium.appspot.com/dl/Mac?type=snapshots ,所以我將其中的 Mac 替換為 Mac_Arm 得到如下地址: https://download-chromium.appspot.com/dl/Mac_Arm?type=snapshots ,開啟果然成功下載了。
下載完成後解壓,就拿到了 Arm 版本的 Chromium。 然而開啟時又出現了新的問題:
Chromium is damaged and can't be opened. You should move it to the Trash.
遇到這個報錯必須要移除對應的驗證:
xattr -c /Applications/Chromium.app
好了,終於可以開啟了,可喜可賀。
API Keys missing
然而當我開啟後又發現 Chromium 上飄著一行提示:
Google API Keys are missing. Some functionality of chromium will be disabled.
不過此時的 Chromium 已經可以正常使用了,但是子曾經曰過:“遇到問題不能坐以待斃”,還是處理下好了。
查了一下原因是 Chromium 的一些功能如 Google 賬號同步等等需要使用 Google API Keys,要處理這個提示大體是兩種思路:
- 可以選擇禁用這個提示,但是這樣 Chromium 的一些功能也就無法使用了。
- 申請 Google API keys,並填入。
如果想要禁用提示可以編輯 Chromium.app > Contents > Info.plist
檔案並新增以下內容:
<key>LSEnvironment</key>
<dict>
<key>GOOGLE_API_KEY</key>
<string>no</string>
<key>GOOGLE_DEFAULT_CLIENT_ID</key>
<string>no</string>
<key>GOOGLE_DEFAULT_CLIENT_SECRET</key>
<string>no</string>
</dict>
而如果想要填入 Google API Keys 則需要去 Google Cloud 申請 API Keys,具體的流程可以參考: https://www.chromium.org/developers/how-tos/api-keys/#acquiring-keys
還有一種方法就是直接使用網上流出的 API Keys,比如這個:
export GOOGLE_API_KEY="AIzaSyCkfPOPZXDKNn8hhgu3JrA62wIgC93d44k"
export GOOGLE_DEFAULT_CLIENT_ID="811574891467.apps.googleusercontent.com"
export GOOGLE_DEFAULT_CLIENT_SECRET="kdloedMFGdGla2P1zacGjAQh"
在 bash 執行上述程式碼將 API Keys 設定到環境變數重啟 Chromium 即可生效。
但是一定需要注意 ⚠️:使用了 API Keys 可能會導致資料資訊洩漏問題,所以如果有敏感資訊切勿使用他人提供的 Key!!!
在 Puppeteer 中使用
由於 Chromium 不是由 Puppeteer 安裝的,所以 Puppeteer 會找不到 Chromium 位置,需要在 Puppeteer 的配置檔案中新增 executablePath
來指定 Chromium 的位置:
const { join } = require('path');
/**
* @type {import("puppeteer").Configuration}
*/
module.exports = {
// Changes the cache location for Puppeteer.
cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
executablePath: '/Applications/Chromium.app/Contents/MacOS/Chromium'
};
參考資料
- https://stackoverflow.com/questions/66002337/is-the-homebrew-chromium-m1-optimised
- https://stackoverflow.com/questions/21276763/google-api-keys-missing-warning-message-when-using-chromium-portable
- https://groups.google.com/a/chromium.org/g/chromium-dev/c/cTPJG7KnBpI?pli=1
- https://www.chromium.org/developers/how-tos/api-keys/#acquiring-keys