表单交互与截图
课程目标
- 🎯 掌握表单元素的自动化操作
- 🎯 实现页面截图与PDF生成
- 🎯 完成模拟登录+数据抓取综合案例
- 🎯 理解浏览器环境隔离机制
一、表单操作核心API
1.1 基础输入操作
// 文本输入(支持模拟输入速度)
await page.type('#username', 'admin', { delay: 100 })
// 清空输入框
await page.$eval('#search', el => el.value = '')
// 或
await page.focus('#search')
await page.keyboard.down('Control')
await page.keyboard.press('A')
await page.keyboard.up('Control')
await page.keyboard.press('Backspace')
// 单选框/复选框
await page.click('#remember-me')
1.2 高级表单组件
// 文件上传(需暴露input元素)
const input = await page.$('input[type="file"]')
await input.uploadFile('./avatar.png')
// 下拉选择(两种方式)
// 方式1:直接修改value
await page.select('#country', 'CN')
// 方式2:模拟点击选择
await page.click('#country option[value="US"]')
// 日期选择器
await page.evaluate(() => {
document.querySelector('#birthday').value = '2023-07-20'
})
二、截图与PDF生成
2.1 页面截图
// 基础截图
await page.screenshot({
path: 'screenshot.png',
fullPage: true, // 截取完整页面
quality: 70, // 图片质量(0-100)
omitBackground: true, // 透明背景
clip: { // 指定区域
x: 0,
y: 0,
width: 800,
height: 600
}
})
// 元素截图
const element = await page.$('#chart-container')
await element.screenshot({
path: 'chart.png',
padding: 10 // 增加边距
})
2.2 PDF生成
await page.pdf({
path: 'report.pdf',
format: 'A4', // 纸张尺寸
margin: {
top: '20mm',
right: '20mm',
bottom: '20mm',
left: '20mm'
},
printBackground: true, // 包含背景
displayHeaderFooter: true,// 显示页眉页脚
headerTemplate: '<div style="font-size:10px">Page <span class="pageNumber"></span></div>',
footerTemplate: '<div style="font-size:10px">Generated by Puppeteer</div>'
})
三、综合实战:baidu模拟登录
3.1 完整实现代码
const puppeteer = require('puppeteer');
const fs = require('fs');
(async () => {
const browser = await puppeteer.launch({
headless: false, // 显示浏览器窗口
executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', // 指定Chrome路径
args: ['--no-sandbox', '--disable-setuid-sandbox'], // 添加沙箱模式禁用选项
env: { NODE_ENV: 'production' }, // 指定环境变量
});
const page = await browser.newPage();
try {
// 设置浏览器视口
await page.setViewport({ width: 1440, height: 900 });
// 导航到登录页
await page.goto('https://www.baidu.com/', {
waitUntil: 'networkidle2',
timeout: 15000,
});
// 等待登录按钮
await page.waitForSelector('#s-top-loginbtn');
// 点击登录按钮
await page.$eval('#s-top-loginbtn', (btn) => btn.click());
await page.waitForSelector('#TANGRAM__PSP_11__userName');
// 输入凭据
await page.type('#TANGRAM__PSP_11__userName', 'your_username', { delay: 50 });
await page.type('#TANGRAM__PSP_11__password', 'your_password', { delay: 50 });
await page.$eval('#TANGRAM__PSP_11__isAgree', (btn) => btn.click());
// 提交表单
await Promise.all([page.waitForNavigation(), page.click('#TANGRAM__PSP_11__submit')]);
// 验证登录成功
await page.$eval('.avatar-user', { timeout: 5000 });
// 保存登录后截图
await page.screenshot({
path: 'github-profile.png',
fullPage: true,
});
// // 提取用户信息
// const userInfo = await page.evaluate(() => ({
// name: document.querySelector('.vcard-names').innerText.trim(),
// bio: document.querySelector('.user-profile-bio').innerText,
// repos: document.querySelectorAll('[itemprop="repositories"]').length,
// }));
// console.log('登录成功:', userInfo);
// 生成PDF报告
await page.pdf({
path: 'github-profile.pdf',
format: 'A4',
});
} catch (err) {
await page.screenshot({ path: 'error.png' });
console.error('登录失败:', err);
} finally {
await browser.close();
}
})();
3.2 关键技术点
- 混合等待策略:
networkidle2
+ 元素显式等待 - 并行操作:
Promise.all
处理导航跳转 - 输入模拟:
delay
参数实现拟人输入 - 多格式输出:同时保存PNG和PDF
四、常见问题解决方案
4.1 表单提交失败
// 方案1:强制提交(当按钮不可点击时)
await page.$eval('form', form => form.submit())
// 方案2:触发验证事件
await page.evaluate(() => {
document.querySelector('#email').dispatchEvent(new Event('blur'))
})
4.2 截图异常处理
// 处理弹窗干扰
page.on('dialog', async dialog => {
await dialog.dismiss();
});
// 处理懒加载内容
await autoScroll(page);
async function autoScroll(page) {
await page.evaluate(async () => {
await new Promise(resolve => {
let totalHeight = 0;
const distance = 100;
const timer = setInterval(() => {
const scrollHeight = document.body.scrollHeight;
window.scrollBy(0, distance);
totalHeight += distance;
if (totalHeight >= scrollHeight) {
clearInterval(timer);
resolve();
}
}, 100);
});
});
}
五、课后作业
5.1 基础任务
- 实现知乎登录自动化并保存个人主页截图
- 抓取天气查询网站数据生成PDF日报
- 添加截图失败的重试机制
5.2 进阶挑战
- 实现滑块验证码绕过(使用移动模拟)
- 开发自动生成网页缩略图工具
- 为PDF添加自定义水印
🛠️ 推荐工具:
- 截图优化:sharp
- PDF处理:pdf-lib
- 验证码识别:tesseract.js
下节课预告:异步控制与事件监听 - 掌握浏览器事件监听与流程控制 ⚙️
配套资源