這個瀏覽器,想必只有開發(fā)者才會用吧?
在數(shù)字世界的深處,隱藏著一種不為普通人所知的瀏覽器形態(tài)——無頭瀏覽器。對于大多數(shù)用戶而言,瀏覽器的存在就是為了瀏覽網(wǎng)頁、獲取信息,而對于開發(fā)者來說,瀏覽器則是他們手中的魔法工具,可以用來測試代碼、抓取數(shù)據(jù),甚至控制網(wǎng)頁。那么,無頭瀏覽器究竟是什么?它又是如何滿足開發(fā)者的需求呢?本文就來一起探索這個看似神秘的瀏覽器。
無頭瀏覽器是什么?
無頭瀏覽器是一種沒有圖形用戶界面(GUI)的網(wǎng)絡(luò)瀏覽器。它可以在后臺運行,并通過編程接口進行控制和操作,而不需要顯示界面。通常,傳統(tǒng)的瀏覽器如 Chrome、Firefox 和 Safari 都具有圖形用戶界面,但這些瀏覽器也提供了無頭模式的選項。
無頭瀏覽器提供了對瀏覽器引擎的完全控制,可以執(zhí)行網(wǎng)頁的加載、渲染和交互操作,并提供了對 DOM 的訪問和操作。通過編程接口,開發(fā)人員可以使用無頭瀏覽器來模擬用戶行為,填寫表單、點擊按鈕、觸發(fā)事件等,以便進行自動化測試或數(shù)據(jù)采集等。
無頭瀏覽器的優(yōu)勢在于它可以在后臺運行,無需顯示瀏覽器窗口,這樣可以節(jié)省系統(tǒng)資源,并且可以在服務(wù)器上進行批量處理和并發(fā)操作。常見的無頭瀏覽器包括 Puppeteer、Selenium WebDriver(使用Headless模式)、PhantomJS 等。其中:
- PhantomJS,又被稱為“無頭瀏覽器之父”,已經(jīng)停止維護。
- Puppeteer 是 Google Chrome 團隊開發(fā)的一款 Node 庫,它提供了一個高級API,用于通過 Node.js控制Chrome或Chromium。Puppeteer 提供了很多有用的功能,如打開頁面、生成PDF、等待頁面加載、處理 JavaScript 異步操作等。
雖然無頭瀏覽器具有許多優(yōu)勢,但也有一些限制需要注意:
- 用戶交互模擬有限:由于無頭瀏覽器不渲染圖形界面,它們可能無法完全模擬用戶的鼠標移動、滾動或復(fù)雜的觸摸手勢等交互。這可能會導(dǎo)致在測試依賴這些交互的網(wǎng)頁應(yīng)用程序的某些方面時出現(xiàn)困難。
- 瀏覽器特定行為:無頭瀏覽器可能無法完全模仿您要測試的目標瀏覽器的特定行為。這可能導(dǎo)致誤報或漏報,并且可能需要在實際瀏覽器中進行額外的測試以確保兼容性。
- 響應(yīng)式設(shè)計測試不足:在測試響應(yīng)式網(wǎng)頁設(shè)計時,無頭瀏覽器可能無法準確模擬不同設(shè)備或屏幕尺寸的行為。因此,仍然需要在真實設(shè)備上測試應(yīng)用,以確保在各個平臺上提供一致的用戶體驗。
- 驗證碼和機器人保護挑戰(zhàn):許多網(wǎng)站使用驗證碼或其他機器人保護機制來防止機器人或爬蟲的自動訪問。無頭瀏覽器可能難以繞過這些保護措施,使得執(zhí)行某些任務(wù)(如網(wǎng)頁抓?。┳兊美щy。
到這里,相信你對無頭瀏覽器已經(jīng)有了一定的了解,下面就來通過 Puppeteer 來看看無頭瀏覽器的使用案例吧。
Puppeteer 是什么?
Puppeteer 是一個基于 Chrome DevTools 協(xié)議的 Node.js 庫,提供了對無頭 Chrome 或 Chrome 瀏覽器的控制。它廣泛應(yīng)用于開發(fā)領(lǐng)域,以下是一些 Puppeteer 在開發(fā)中的應(yīng)用場景的例資:
- 自動化測試:可以模擬用戶在瀏覽器中的行為,如點擊按鈕、填寫表單、觸發(fā)事件等,因此在自動化測試中非常有用。
- 網(wǎng)頁截圖和PDF生成:可以加載網(wǎng)頁并生成截圖或PDF文件。這在需要生成頁面快照、生成報告或進行網(wǎng)頁內(nèi)容的可視化檢查時非常有用。
- 網(wǎng)頁爬蟲和數(shù)據(jù)采集:可以模擬用戶在瀏覽器中的行為,因此可以用于構(gòu)建網(wǎng)絡(luò)爬蟲和數(shù)據(jù)采集工具。
- 性能分析和優(yōu)化:可以用于測量和分析網(wǎng)頁的性能指標,如加載時間、資源使用情況等。
- UI交互測試:可以使用Puppeteer模擬用戶與網(wǎng)頁的交互,檢查UI元素的可見性、位置和樣式等,以確保頁面在不同場景下的正確顯示和交互。
Puppeteer API 可用于截取屏幕截圖、創(chuàng)建 PDF、導(dǎo)航頁面以及從頁面獲取信息等。
Puppeteer 怎么用?
下面來使用 Puppeteer 進行屏幕截圖、創(chuàng)建PDF、自動化操作。
首先,在終端中執(zhí)行以下命令來安裝 puppeteer:
npm i puppeteer
屏幕截圖
接下來,創(chuàng)建一個 JavaScript 文件,將其命名為 puppeteer.js,在其中添加以下代碼:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.yuque.com/cuggz');
await page.screenshot({path: '前端充電寶.png'});
browser.close();
})();
這段代碼很簡單,大概流程如下:
- 引入Puppeteer庫:第一行引入了 Puppeteer
- 啟動瀏覽器:通過調(diào)用puppeteer.launch()方法來啟動一個無頭瀏覽器實例。這將返回一個Browser對象,代表了一個瀏覽器實例。
- 創(chuàng)建頁面:通過調(diào)用browser.newPage()方法來創(chuàng)建一個新的頁面。這將返回一個Page對象,代表了一個網(wǎng)頁。
- 打開網(wǎng)頁:使用page.goto()方法打開指定的URL,瀏覽器將加載該網(wǎng)頁。
- 截圖:使用page.screenshot()方法對當前頁面進行截圖,并將截圖保存到指定的路徑。
- 關(guān)閉瀏覽器:通過調(diào)用browser.close()方法來關(guān)閉瀏覽器實例,釋放資源。
可以通過設(shè)置 fullPage: true 來實現(xiàn)全屏幕截圖:
await page.screenshot({ path: 'cuggz.png', fullPage: true})
這樣,屏幕截圖就完成了。
生成 PDF
接下來使用 Puppeteer 將頁面生成一個 PDF。先創(chuàng)建一個 puppeteerpdf.js文件,在文件中添加以下代碼:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.yuque.com/cuggz', {waitUntil: 'networkidle'});
await page.pdf({path: '前端充電寶.pdf', format: 'A4'});
browser.close();
})();
這段代碼和上面的例子差不多。這里的 waitUntil: 'networkidle' 表示僅當網(wǎng)絡(luò)活動保持“空閑”狀態(tài)至少達到 networkIdleTimeout 毫秒(默認為 1000 毫秒)時,才認為站點導(dǎo)航已完成,然后才會執(zhí)行 PDF 生成操作。
自動化操作
下面來使用 Puppeteer 進行頁面導(dǎo)航、自動化表單提交和鍵盤輸入,并顯示表單提交結(jié)果。
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://google.com', {waitUntil: 'networkidle'});
// 在搜索欄中輸入查詢
await page.type('前端充電寶');
await page.click('input[type="submit"]');
// 等待結(jié)果顯示
await page.waitForSelector('h3 a');
// 從頁面中提取結(jié)果
const links = await page.evaluate(() => {
const anchors = Array.from(document.querySelectorAll('h3 a'));
return anchors.map(anchor => anchor.textContent);
});
console.log(links.join('\n'));
browser.close();
})();
這里使用 page.type() 函數(shù)定義要鍵入的查詢,并使用 page.click() 函數(shù)模擬單擊。page.waitForSelector() 函數(shù)用于等待選擇器檢查是否加載了所需的內(nèi)容。
page.evaluate() 函數(shù)允許在頁面上下文中運行腳本。上面的函數(shù)從 Google 搜索結(jié)果中獲取所有鏈接并將它們存儲在一個數(shù)組中。