puppeteer 常见问题

712 阅读2分钟

1. TimeoutError: Navigation timeout of 30000 ms exceeded

image.png

一般出现这个问题是因为网络原因加载部分js 等资源失败,如果不影响网站使用可以跳过这些js的加载,找到对应的js 域名或者url 添加进去

await page.setRequestInterception(true);
  page.on('request', (request) => {
   const url = request.url();
   if (['google'].includes(url) {
     request.abort();
   } else {
     request.continue();
   }
});

1.1 请求拦截

// 启用请求拦截
  await page.setRequestInterception(true);

  page.on('request', (interceptedRequest) => {
    if (interceptedRequest.url().includes('/your-endpoint')) { // 根据需要拦截的接口 URL 进行匹配
      interceptedRequest.respond({
        status: 200,
        contentType: 'application/json',
        body: '{"message": "Modified response data"}', // 更改响应数据为您想要的内容
      });
    } else {
      interceptedRequest.continue();
    }
  });

2. 选择非标准下拉框的值,如el-select

等待下拉框加载成功,点击下拉框对应的元素,等待下拉选项加载成功,点击对应的下列选项

await page.waitForSelector('.ant-select-selection-item') // 等待下拉框元素加载完成
await page.click('.ant-select-selection-item') // 点击下拉框出现下拉选项
await page.waitForTimeout(1000)
await page.waitForSelector('.ant-select-item-option-content') //等待下拉选项出现
    
await page.click('div[title="xxx的公司"]') // 选中对应的下拉选项
await page.click('button[type="submit"]') // 点击登录按钮
await page.waitForNavigation() // 等待页面跳转完成

3. 如果获取某个接口的响应数据

let token = '';
page.on('response', async (response) => {
  const url = response.url(); // 所有接口的url
  if (response.request().method() === 'POST' && url ==='https://xxxx/api/enterprise/token') { // 匹配到对应的接口地址和对应的方法
        const data = await response.json();// 获取对应的接口响应数据
        token = data.token // 获取对一个的token
      }
})

4. 清空输入框里面的内容

const inputValue = await page.$eval('input[type="text"]', el => el.value); // 获取元素的内容
for (let i = 0; i < inputValue.length; i++) {
   await page.keyboard.press('Backspace'); // 模拟点击删除键
}

5. 登录网站成功后,获取localStorage

const token = await page.evaluate(() => { // 相当于在控制台执行js脚本
   return localStorage.getItem('token'); // 获取localStorage对应的内容并返回
});

6. 登录网站成功后,获取Cookie

const cookies = await page.cookies(); //获取当前域名下所有的cookie,返回是一个数组
const sessionid = cookies.find(cookie => cookie.name === 'sessionid').value; // 获取到想要的cookie值

7. $$eval,$eval,evaluate 的区别

$$eval的回调函数获取 对应选择器的所有元素,返回值是数组, 可以打印console.log

$eval的回调函数获取 对应选择器的第一个元素,可以打印console.log

evaluate执行js脚本,直接打印console.log,不会输入控制台日志,需要添加一下监听事件

// 添加控制台事件监听器
page.on('console', (message) => {
   if (message.type() === 'log') {
     console.log('Console output:', message.text());
   }
});