1. 简介
Puppeteer 是一个由谷歌 Chrome 开发团队发布的 Node.js 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。
1.1. 主要功能
-
生成截图和PDF:可以生成页面的屏幕截图和 PDF。
-
抓取和预渲染:能够抓取单页应用(SPA)并生成预渲染内容,即服务器端渲染(SSR)。
-
自动化测试:可以自动提交表单、进行 UI 测试、模拟键盘输入等,创建自动化测试环境。
-
性能分析:捕获站点的时间线跟踪,帮助诊断性能问题。
-
测试浏览器扩展:支持测试 Chrome 扩展程序。
1.2. 使用场景
-
前端自动化测试:帮助前端工程师快速测试和优化前端代码。
-
爬虫:用于网络爬虫,获取网页数据。
-
页面渲染:用于服务器端渲染,提高页面加载速度
2. 示例笔记
import puppeteer, { Browser, Frame, Page } from 'puppeteer'
// 启动浏览器
const browser = await puppeteer.launch({
headless: true,
// userDataDir: '../storage', // 是否需要存储数据
args: ['--no-sandbox']
})
// 新建页面
const page = await browser.newPage()
// 跳转到新页面
await page.goto('https://www.timelessq.com')
2.1. 查找元素
const usernameInput = page.locator(`input[type='text']`)
const passwordInput = page.locator(`input[type='password']`)
const $username = await usernameInput.waitHandle()
const $password = await passwordInput.waitHandle()
// 或者使用waitForSelector
const $login = await page.waitForSelector(`::-p-xpath(//span[text()='登录'])`, {
timeout: 3000,
})
// $$
const $container = (await page.$$(`div[class='layout'] > div`)).at(-1)
2.2. 操作
// 输入用户名
await $username.click()
await $username.type(email, { delay: 100 })
// 输入密码
await $pwd.click()
await $pwd.type(password, { delay: 100 })
// 获取文本内容
const text = await option.evaluate((el) => el.innerText)
2.3. 截图
const $bgImg = await page.waitForSelector("img[id='captcha_verify_image']")
const backgroundImg = await $bgImg.screenshot({ encoding: 'base64' })
2.4. 获取请求响应
const response = await page.waitForResponse(
(response) => response.url().includes('https://api.timelessq.com/time') && response.status() === 200,
)
const result = await response.json()
2.5. 拖动验证码
import { BoundingBox, Page } from 'puppeteer'
// 缓动函数(easeOutQuad)
function easeOutQuad(t: number): number {
return t * (2 - t)
}
// 生成人类化轨迹
function generateHumanTrajectory(distance: number, steps: number = 30): { x: number; y: number }[] {
const trajectory: { x: number; y: number }[] = []
let current = 0
let prevPosition = 0
for (let i = 0; i < steps; i++) {
const t = i / (steps - 1)
const eased = easeOutQuad(t)
const newPosition = eased * distance
// 添加随机扰动(幅度逐渐减小)
const randomFactor = 1 - t // 越到后期扰动越小
const deltaX = newPosition - prevPosition
const deltaY = (Math.random() * 4 - 2) * randomFactor // Y轴扰动
trajectory.push({
x: deltaX,
y: deltaY,
})
prevPosition = newPosition
current = newPosition
}
// 精度补偿确保最终到达目标
const totalX = trajectory.reduce((sum, step) => sum + step.x, 0)
const diff = distance - totalX
if (Math.abs(diff) > 0.001) {
trajectory[steps - 1].x += diff
}
return trajectory
}
// 执行人类化拖动
function humanDrag(page: Page, sliderBox: BoundingBox, distance: number): Promise<void> {
const startPoint = {
x: sliderBox.x + sliderBox.width / 2,
y: sliderBox.y + sliderBox.height / 2,
}
// 加入初始随机偏移
await page.mouse.move(startPoint.x + Math.random() * 3 - 1.5, startPoint.y + Math.random() * 3 - 1.5, { steps: 5 })
await page.mouse.down()
const trajectory = generateHumanTrajectory(distance)
let currentPosition = { ...startPoint }
for (const [index, step] of trajectory.entries()) {
currentPosition.x += step.x
currentPosition.y += step.y
// 添加非匀速移动效果
const moveSteps = index < trajectory.length / 2 ? 5 : 10
await page.mouse.move(currentPosition.x + Math.random() * 2 - 1, currentPosition.y + Math.random() * 2 - 1, {
steps: moveSteps,
})
// 动态间隔时间(前期快后期慢)
const baseDelay = index < trajectory.length / 2 ? 20 : 40
await delay(baseDelay + Math.random() * 30)
// 随机添加停顿
if (Math.random() < 0.2) {
await delay(50 + Math.random() * 100)
}
}
// 最终微调(模拟人类修正行为)
for (let i = 0; i < 2; i++) {
await page.mouse.move(currentPosition.x + (Math.random() * 2 - 1), currentPosition.y + (Math.random() * 2 - 1), {
steps: 3,
})
await delay(50)
}
await page.mouse.up()
}
3. 常见问题
3.1. Linux安装缺少依赖
安装完puppeteer后,到/root/.cache/puppeteer/chrome/linux-xxxxx/chrome-linux64/目录下,执行 ldd chrome | grep not
以检查缺少哪些依赖。
比如,我的服务器就输出:
libglib-2.0.so.0 => not found
libgobject-2.0.so.0 => not found
libgio-2.0.so.0 => not found
libatk-1.0.so.0 => not found
libatk-bridge-2.0.so.0 => not found
libcups.so.2 => not found
libxkbcommon.so.0 => not found
libatspi.so.0 => not found
libXcomposite.so.1 => not found
libXdamage.so.1 => not found
libXfixes.so.3 => not found
libXrandr.so.2 => not found
libgbm.so.1 => not found
libpango-1.0.so.0 => not found
libcairo.so.2 => not found
libasound.so.2 => not found
然后把这个丢给ai分析,或者搜索看缺少哪些依赖包,然后使用apt安装依赖
apt install libglib2.0-0 libatk1.0-0 libatk-bridge2.0-0 libcups2 libxkbcommon0 libatspi2.0-0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libpango-1.0-0 libcairo2 libasound2
3.2. sandbox
使用root运行,sandbox报错
const browser = await puppeteer.launch({
headless: true,
args: [
'--no-sandbox'
]
})
还没有评论,快来抢第一吧