Node使用Puppeteer監(jiān)聽(tīng)并打印網(wǎng)頁(yè)的接口請(qǐng)求
在現(xiàn)代 Web 開(kāi)發(fā)中,前端頁(yè)面與后端服務(wù)之間的交互頻繁依賴(lài)于各種接口請(qǐng)求。無(wú)論是調(diào)試前端代碼、分析網(wǎng)絡(luò)性能,還是進(jìn)行安全測(cè)試,能夠監(jiān)聽(tīng)并打印網(wǎng)頁(yè)的接口請(qǐng)求都是非常有用的。而 Puppeteer,這個(gè)由谷歌開(kāi)發(fā)的 Node 庫(kù),為我們提供了一個(gè)強(qiáng)大的工具來(lái)實(shí)現(xiàn)這一目標(biāo)。
一、Puppeteer 簡(jiǎn)介
Puppeteer 是一個(gè) Node 庫(kù),它提供了高級(jí)的 API 來(lái)通過(guò) DevTools 協(xié)議控制 Chrome 或 Chromium。它默認(rèn)以無(wú)頭模式運(yùn)行,但也可以配置為運(yùn)行“有頭”模式。借助 Puppeteer,我們可以生成頁(yè)面截圖和 PDF、爬取 SPA(單頁(yè)應(yīng)用)并生成預(yù)渲染內(nèi)容、自動(dòng)化表單提交、UI 測(cè)試、鍵盤(pán)輸入等。在我們的場(chǎng)景中,它還可以幫助我們監(jiān)聽(tīng)并打印網(wǎng)頁(yè)的接口請(qǐng)求。
二、準(zhǔn)備工作
在開(kāi)始之前,你需要確保你的開(kāi)發(fā)環(huán)境中已經(jīng)安裝了 Node.js 和 npm(Node 包管理器)。然后,你可以通過(guò) npm 安裝 Puppeteer。
npm install puppeteer
安裝完成后,你就可以開(kāi)始編寫(xiě)代碼來(lái)監(jiān)聽(tīng)并打印網(wǎng)頁(yè)的接口請(qǐng)求了。
三、監(jiān)聽(tīng)并打印接口請(qǐng)求的代碼實(shí)現(xiàn)
以下是一個(gè)簡(jiǎn)單的示例代碼,展示如何使用 Puppeteer 監(jiān)聽(tīng)并打印網(wǎng)頁(yè)的接口請(qǐng)求。
const puppeteer = require('puppeteer'); (async () => { // 啟動(dòng)瀏覽器 const browser = await puppeteer.launch({ headless: false, // 設(shè)置為 false 方便觀察瀏覽器行為 slowMo: 50, // 放慢執(zhí)行速度,方便觀察 }); // 打開(kāi)新頁(yè)面 const page = await browser.newPage(); // 監(jiān)聽(tīng)網(wǎng)絡(luò)請(qǐng)求 page.on('request', request => { if (request.method() === 'GET') { console.log(`GET 請(qǐng)求: ${request.url()}`); } else if (request.method() === 'POST') { console.log(`POST 請(qǐng)求: ${request.url()}`); console.log(`POST 請(qǐng)求數(shù)據(jù): ${request.postData()}`); } request.continue(); // 繼續(xù)處理請(qǐng)求 }); // 打開(kāi)目標(biāo)網(wǎng)頁(yè) await page.goto('https://example.com'); // 等待一段時(shí)間,觀察接口請(qǐng)求 await page.waitForTimeout(5000); // 關(guān)閉瀏覽器 await browser.close(); })();
代碼解析
啟動(dòng)瀏覽器:通過(guò) puppeteer.launch 方法啟動(dòng)瀏覽器。你可以設(shè)置 headless 參數(shù)為 false,以便在調(diào)試時(shí)能夠看到瀏覽器的界面。
打開(kāi)新頁(yè)面:使用 browser.newPage 方法打開(kāi)一個(gè)新頁(yè)面。
監(jiān)聽(tīng)網(wǎng)絡(luò)請(qǐng)求:通過(guò) page.on('request', ...) 方法監(jiān)聽(tīng)頁(yè)面的網(wǎng)絡(luò)請(qǐng)求。當(dāng)頁(yè)面發(fā)出請(qǐng)求時(shí),會(huì)觸發(fā)這個(gè)事件。你可以通過(guò) request.method() 獲取請(qǐng)求方法(如 GET、POST),通過(guò) request.url() 獲取請(qǐng)求的 URL,對(duì)于 POST 請(qǐng)求,還可以通過(guò) request.postData() 獲取請(qǐng)求的正文數(shù)據(jù)。
繼續(xù)處理請(qǐng)求:在監(jiān)聽(tīng)到請(qǐng)求后,調(diào)用 request.continue() 方法繼續(xù)處理請(qǐng)求。如果不調(diào)用這個(gè)方法,請(qǐng)求會(huì)被攔截,頁(yè)面將無(wú)法正常加載。
打開(kāi)目標(biāo)網(wǎng)頁(yè):使用 page.goto 方法打開(kāi)目標(biāo)網(wǎng)頁(yè)。你可以將 'https://example.com' 替換為你想要監(jiān)聽(tīng)接口請(qǐng)求的網(wǎng)頁(yè)地址。
等待一段時(shí)間:通過(guò) page.waitForTimeout 方法等待一段時(shí)間,以便觀察頁(yè)面加載過(guò)程中發(fā)出的接口請(qǐng)求。
關(guān)閉瀏覽器:最后,通過(guò) browser.close 方法關(guān)閉瀏覽器。
基于上面的代碼,再完善一個(gè),于json格式輸出
async function printPageRequests(url = 'https://www.baidu.com', action = '', format = 'txt') { console.log(TAG, `printPageRequests start, url:${url}, action:${action}', format:${format}`) // const browser = await puppeteer.launch({ headless: false }); const browser = await puppeteer.launch({headless: true}); const page = await browser.newPage(); page.on('request', (request) => { // const resourceType = request.resourceType(); // if (resourceType === 'fetch') { // console.log(`Fetch Request: ${request.method()} ${request.url()}`); // } request.continue(); }); page.on('response', async (response) => { const request = response.request(); const resourceType = request.resourceType(); if (resourceType === 'fetch' || resourceType === 'xhr') { const requestInfo = `Fetch Response: ${request.method()} ${request.url()} - Status: ${response.status()} ` if (action === 'printBody') { if (format === 'txt') { try { // 嘗試獲取響應(yīng)內(nèi)容 const responseBody = await response.text(); console.log(`${requestInfo} txt Body: ${responseBody}`); } catch (error) { console.error(`${requestInfo}, Failed to get response body: ${error}`); } } else if (format === 'json') { try { // 嘗試獲取響應(yīng)內(nèi)容 const responseBody = await response.json(); console.log(`${requestInfo}, Response json Body: ${JSON.stringify(responseBody, null, 2)}`); } catch (error) { console.error(`Failed to get response body: ${error}`); } } } } }); await page.setRequestInterception(true); try { console.log(`Navigating to ${url}`); await page.goto(url, {timeout: 60000}); console.log(`Navigation completed`); } catch (error) { if (error.name === 'TimeoutError') { console.error(`Navigation timeout exceeded for ${url}`); } else { throw error; } } await browser.close(); console.log(TAG, 'printPageRequests end') }
看一個(gè)效果,txt格式
再看一個(gè)效果,json格式
PS:上面是我把代碼放到了自己的一個(gè)工具集中,并使用了commander管理來(lái)不斷的豐富工具模塊
四、實(shí)際應(yīng)用場(chǎng)景
1.前端調(diào)試
在前端開(kāi)發(fā)過(guò)程中,開(kāi)發(fā)者常常需要了解頁(yè)面是如何與后端服務(wù)交互的。通過(guò)使用 Puppeteer 監(jiān)聽(tīng)接口請(qǐng)求,開(kāi)發(fā)者可以清晰地看到每個(gè)請(qǐng)求的 URL、請(qǐng)求方法、請(qǐng)求數(shù)據(jù)等信息,從而快速定位問(wèn)題,提高調(diào)試效率。
2.網(wǎng)絡(luò)性能分析
通過(guò)監(jiān)聽(tīng)并打印接口請(qǐng)求,我們可以分析每個(gè)請(qǐng)求的響應(yīng)時(shí)間、請(qǐng)求大小等信息,從而評(píng)估網(wǎng)頁(yè)的網(wǎng)絡(luò)性能。這對(duì)于優(yōu)化網(wǎng)頁(yè)加載速度、提升用戶(hù)體驗(yàn)非常有幫助。
3.安全測(cè)試
在安全測(cè)試中,監(jiān)聽(tīng)接口請(qǐng)求可以幫助我們發(fā)現(xiàn)潛在的安全問(wèn)題。例如,通過(guò)檢查請(qǐng)求數(shù)據(jù)是否包含敏感信息、請(qǐng)求的 URL 是否符合預(yù)期等,我們可以及時(shí)發(fā)現(xiàn)并修復(fù)安全漏洞。
五、注意事項(xiàng)
請(qǐng)求攔截的限制:雖然 Puppeteer 提供了強(qiáng)大的請(qǐng)求攔截功能,但它也有一些限制。例如,它無(wú)法攔截瀏覽器內(nèi)部的一些請(qǐng)求,如字體加載請(qǐng)求等。此外,對(duì)于一些復(fù)雜的請(qǐng)求,如帶有 WebSocket 的請(qǐng)求,監(jiān)聽(tīng)和處理可能會(huì)更加復(fù)雜。
性能影響:監(jiān)聽(tīng)并處理大量的請(qǐng)求可能會(huì)對(duì)瀏覽器的性能產(chǎn)生一定影響。在實(shí)際使用中,需要注意合理控制監(jiān)聽(tīng)的范圍和頻率,避免對(duì)頁(yè)面的正常加載和運(yùn)行造成過(guò)大的干擾。
隱私和安全問(wèn)題:在監(jiān)聽(tīng)接口請(qǐng)求時(shí),可能會(huì)涉及到一些敏感信息。因此,在使用 Puppeteer 監(jiān)聽(tīng)接口請(qǐng)求時(shí),需要注意保護(hù)用戶(hù)的隱私和數(shù)據(jù)安全,避免泄露敏感信息。
六、總結(jié)
通過(guò)使用 Puppeteer,我們可以輕松地監(jiān)聽(tīng)并打印網(wǎng)頁(yè)的接口請(qǐng)求,這為前端調(diào)試、網(wǎng)絡(luò)性能分析和安全測(cè)試等提供了極大的便利。在實(shí)際開(kāi)發(fā)和測(cè)試中,合理利用 Puppeteer 的這一功能,可以幫助我們更好地理解和優(yōu)化網(wǎng)頁(yè)的交互行為,提升開(kāi)發(fā)效率和產(chǎn)品質(zhì)量。
到此這篇關(guān)于Node使用Puppeteer監(jiān)聽(tīng)并打印網(wǎng)頁(yè)的接口請(qǐng)求的文章就介紹到這了,更多相關(guān)Puppeteer監(jiān)聽(tīng)并打印網(wǎng)頁(yè)接口請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Koa2中間件的作用及路由實(shí)現(xiàn)實(shí)例詳解
這篇文章主要介紹了Koa2中間件的作用及路由實(shí)現(xiàn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05通過(guò)nodejs 服務(wù)器讀取HTML文件渲染到頁(yè)面的方法
今天小編就為大家分享一篇通過(guò)nodejs 服務(wù)器讀取HTML文件渲染到頁(yè)面的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05node.js與C語(yǔ)言 實(shí)現(xiàn)遍歷文件夾下最大的文件,并輸出路徑,大小
這篇文章主要介紹了node.js與C語(yǔ)言 實(shí)現(xiàn)遍歷文件夾下最大的文件,并輸出路徑,大小的相關(guān)資料,需要的朋友可以參考下2017-01-01node連接kafka2.0實(shí)現(xiàn)方法示例
這篇文章主要介紹了node連接kafka2.0,nodejs連接kafka2.0的實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了kafka2.0的功能、原理、以及node.js連接kafka2.0的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2023-05-05Nodejs學(xué)習(xí)item【入門(mén)手上】
這篇文章主要介紹了Nodejs學(xué)習(xí)item【入門(mén)手上】,需要的朋友可以參考下2016-05-05Node.js 中 cookie-parser 依賴(lài)安裝使用詳解
文章介紹了如何在Node.js中使用cookie-parser中間件來(lái)解析、設(shè)置、簽名和清除HTTP請(qǐng)求中的Cookie,感興趣的朋友一起看看吧2025-02-02用NODE.JS中的流編寫(xiě)工具是要注意的事項(xiàng)
Nodejs讀寫(xiě)流流的傳輸過(guò)程默認(rèn)是以buffer的形式傳輸?shù)?除非你給他設(shè)置其他編碼形式, 小伙伴可以參考下。2016-03-03node使用querystring內(nèi)置模塊解決分頁(yè)返回?cái)?shù)據(jù)太多導(dǎo)致json.parse()解析報(bào)錯(cuò)問(wèn)題
這篇文章主要介紹了node使用querystring內(nèi)置模塊解決分頁(yè)返回?cái)?shù)據(jù)太多導(dǎo)致json.parse()解析報(bào)錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-09-09