【利用AI让知识体系化】深入浅出Puppeteer(一)https://developer.aliyun.com/article/1426082
4. Puppeteer的高级功能
4.1 模拟用户行为
通过 Puppeteer,可以模拟用户的页面行为,实现一些自动化的操作,比如点击按钮、输入文本、滚动页面等。
以下是 Puppeteer 模拟用户行为的示例代码:
const puppeteer = require('puppeteer'); async function run() { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://example.com'); // 点击元素 const button = await page.$('button'); await button.click(); // 输入文本 await page.type('input[type="text"]', 'Puppeteer'); // 模拟键盘操作 await page.keyboard.press('Enter'); // 模拟鼠标操作 await page.mouse.click(100, 100); // 滚动页面 await page.evaluate(() => { window.scrollBy(0, 100); // 向下滚动页面 100 像素 }); // 等待 1 秒 await page.waitForTimeout(1000); // 关闭浏览器 await browser.close(); } run();
在以上示例中,使用 page.$() 方法获取按钮元素,然后使用 button.click() 方法模拟点击操作。接着,使用 page.type() 方法模拟在输入框中输入文本,使用 page.keyboard.press() 方法模拟按下 Enter 键。之后,使用 page.mouse.click() 方法模拟鼠标点击,使用 page.evaluate() 方法滚动页面。最后,使用 page.waitForTimeout() 方法等待 1 秒,然后关闭浏览器。
除了以上示例中的操作之外,还可以模拟其他用户行为,比如悬停、拖拽等。通过这些方法,可以方便地实现各种自动化页面操作的需求。
4.2 处理表单和输入操作
在使用 Puppeteer 进行自动化测试时,经常需要处理表单及其输入操作。
以下是 Puppeteer 处理表单和输入操作的示例代码:
const puppeteer = require('puppeteer'); async function run() { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://www.baidu.com'); // 等待搜索框出现并点击 await page.waitForSelector('#kw'); await page.click('#kw'); // 输入文本 await page.type('#kw', 'Puppeteer'); // 点击搜索按钮 await page.click('#su'); // 等待搜索结果页面加载完成 await page.waitForSelector('#content_left'); // 获取搜索结果数量 const resultCount = await page.evaluate(() => { return document.querySelectorAll('.result').length; }); console.log(`搜索结果数量:${resultCount}`); // 关闭浏览器 await browser.close(); } run();
在以上示例中,使用 page.waitForSelector() 方法等待搜索框出现,然后使用 page.click() 方法点击搜索框,并使用 page.type() 方法输入文本。接着,使用 page.click() 方法点击搜索按钮,并使用 page.waitForSelector() 方法等待搜索结果页面加载完成。之后,使用 page.evaluate() 方法获取搜索结果数量并输出。最后,关闭浏览器。
在处理表单时,有几个常用的方法:
page.type(selector, value[, options]):在指定的元素上输入文本,其中selector是元素选择器,value是要输入的文本,options是一些可选参数,比如delay表示输入每个字符的间隔时间,timeout表示等待元素可见的最大时间等;page.click(selector[, options]):点击指定的元素,其中selector是元素选择器,options是一些可选参数,比如button表示要使用哪个鼠标键点击,clickCount表示点击次数,delay表示点击后等待的时间等;page.select(selector, ...values):选择下拉框中的选项,其中selector是下拉框的选择器,values是要选择的选项值。
通过这些方法,可以方便地处理表单及其输入操作。
4.3 处理JavaScript的动态渲染
在使用 Puppeteer 进行自动化测试时,可能需要处理 JavaScript 动态渲染的页面。Puppeteer 默认情况下支持等待页面中的所有网络请求,但对于 JavaScript 动态渲染的数据,需要使用额外的方法来等待页面渲染完成。
以下是 Puppeteer 处理 JavaScript 动态渲染的示例代码:
const puppeteer = require('puppeteer'); async function run() { const browser = await puppeteer.launch(); const page = await browser.newPage(); // 访问使用 JavaScript 动态渲染的页面 await page.goto('https://example.com'); // 等待指定元素出现 const selector = 'div.result'; await page.waitForSelector(selector); // 获取所有结果 const results = await page.evaluate((selector) => { const elements = Array.from(document.querySelectorAll(selector)); return elements.map((elem) => elem.innerText.trim()); }, selector); console.log(results); // 关闭浏览器 await browser.close(); } run();
以上示例代码中,通过 page.waitForSelector() 方法等待页面中指定的元素出现,使用 page.evaluate() 方法获取指定元素的文本内容,并输出到控制台。最后,关闭浏览器。
除了 page.waitForSelector() 方法之外,Puppeteer 还提供了其他方法来等待页面渲染完成,包括:
page.waitForNavigation([options]):等待页面的导航完成;page.waitForFunction(pageFunction[, options[, ...args]]):等待指定的函数在页面上执行完成,可以传入函数参数;page.waitForTimeout(timeout):等待指定时间。
通过这些方法,可以处理 JavaScript 动态渲染的页面,确保在正确的时间点获取到需要的数据。
4.4 网络请求与响应处理
在使用 Puppeteer 进行自动化测试时,常常需要处理网络请求与响应。
Puppeteer 提供了一些方法来拦截网络请求、修改请求 / 响应头、获取请求 / 响应数据等。
以下是 Puppeteer 处理网络请求与响应的示例代码:
const puppeteer = require('puppeteer'); async function run() { const browser = await puppeteer.launch(); const page = await browser.newPage(); // 拦截网络请求 await page.setRequestInterception(true); page.on('request', (request) => { // 忽略图片请求 if (request.resourceType() === 'image') { request.abort(); } else { request.continue(); } }); // 访问页面 await page.goto('https://www.baidu.com'); // 获取一张图片 const image = await page.$('img'); // 修改图片请求头 await page.setRequestInterception(true); page.on('request', (request) => { if (request.resourceType() === 'image' && request.url() === image.src()) { request.continue({ headers: { ...request.headers(), 'Referer': 'https://example.com' } }); } else { request.continue(); } }); // 确保图片加载完成 await image.evaluate((img) => img.decode()); // 获取页面源代码 const html = await page.content(); // 获取所有网络请求信息 const requests = await page._client.send('Network.getAllRequestsWithResponse'); // 关闭浏览器 await browser.close(); } run();
在以上示例中,使用 page.setRequestInterception(true) 方法拦截网络请求,并通过 page.on('request', ...) 方法监听请求事件。在事件处理程序中,可以通过 request.resourceType() 方法判断请求类型,通过 request.url() 方法获取请求的 URL,使用 request.continue() 方法继续请求,或使用 request.abort() 方法取消请求。在示例中,忽略了图片请求。
使用 page.$() 方法获取一张图片元素,然后通过 page.on('request', ...) 方法监听请求事件,判断图片请求并修改请求头中的 Referer 字段。在获取图片前,使用 img.decode() 方法确保图片加载完成。之后,使用 page.content() 方法获取页面源代码,使用 _client.send('Network.getAllRequestsWithResponse') 方法获取所有网络请求信息,并输出到控制台。最后,关闭浏览器。
除了以上示例中的方法之外,Puppeteer 还提供了其他一些方法来处理网络请求与响应,包括:
page.setExtraHTTPHeaders(headers):设置额外的请求头;page.waitForRequest(urlOrPredicate[, options]):等待指定的网络请求,请参考page.waitForNavigation()方法;page.waitForResponse(urlOrPredicate[, options]):等待指定的网络响应,请参考page.waitForNavigation()方法。
通过这些方法,可以方便地处理网络请求与响应,实现各种自动化测试需求。
【利用AI让知识体系化】深入浅出Puppeteer(三)https://developer.aliyun.com/article/1426084