1. puppeteer 和 puppeteer-core
安装 puppeteer 会默认下载一个最新版本的 chrome
浏览器;
安装 puppeteer-core
,不会安装 chrome
, 若要程序打开浏览器运行时,需手动指定电脑系统安装的 chrome 浏览器路径
;
2. puppeteer-core
指定系统 chrome 浏览器路径
import puppeteer from 'puppeteer-core';
// launch 添加 executablePath 参数
await puppeteer.launch({executablePath: '/path/to/Chrome'});
查看本机 chrome
路径: 在 chrome 浏览器中输入地址 chrome://version
3. 简单启用示例
const userAgents = [
// 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
// 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
// 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36 QIHU 360SE',
// 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
// 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
];
// 随机选择一个 User-Agent
function getRandomUserAgent () {
return userAgents[Math.floor(Math.random() * userAgents.length)];
}
(async () => {
// Launch the browser and open a new blank page
const browser = await puppeteer.launch({
userDataDir: './userData', // 指定存放用户数据目录
headless: false, // 关闭无头模式,会打开 chrome 浏览器
args: [
'--start-maximized', // 窗口最大化
// `--proxy-server=${proxySettings.proxy}`, // 配置代理
'--no-sandbox',
'--disable-setuid-sandbox'
],
defaultViewport: { // 模式页面视图大小
width: 1920,
height: 1080,
},
devtools: true, // 打开开发者工具
});
try {
let isLogin = false
const page = await browser.newPage()
// 设置随机 User-Agent
const userAgent = getRandomUserAgent();
await page.setUserAgent(userAgent);
// 从文件读取 cookies
const cookiesJson = fs.readFileSync('qcccookies.json', 'utf8');
if (cookiesJson) {
const cookies = JSON.parse(cookiesJson);
// 在页面加载之前设置 cookies
cookies && await page.setCookie(...cookies); // 使用扩展运算符展开 cookies 数组
}
// 进入目标页
await page.goto('https://www.baidu.com', {
waitUntil: "networkidle2",
})
// 判断是否有账户头像,有则说明自动登录成功
const userImg = await page.$('xxxxx.img')
if (userImg) {
isLogin = true;
}
/**
* 登录 在页面 input 中数据内容并登录
*/
if (!isLogin) {
// insert name
await page.type('body > input', config.account, { delay: typeDelay });
// insert pwd
await page.type('body > input', config.pwd, { delay: typeDelay });
// 点击登录
await page.click('body > button')
// 页面截图
await page.screenshot({ path: "test2.png" })
// 等待进行手动登录验证,进入页面
await page.waitForNavigation({
waitUntil: 'load'
})
// 获取当前页面的所有 cookies
{
const cookies = await page.cookies();
console.log(cookies);
// 将 cookies 转换为 JSON 字符串并保存到文件
await fs.writeFileSync('qcccookies.json', JSON.stringify(cookies, null, 2));
}
}
// 获取打开的页面栈
const pages = await browser.pages();
console.log(pages);
// 获取最新打开的页面
let newPage = null
await new Promise((resolve) => {
browser.on('targetcreated', async (target) => {
if (target.opener() === page.target()) {
newPage = await target.page();
}
});
});
if (newPage) {
await sleep(3000)
await newPage.waitForSelector('body'); // 例如等待页面加载完成
// 页面存 pdf
await page.pdf({
path: 'xxxx.pdf',
format: 'A3',
// displayHeaderFooter: true,
margin: {
top: '5mm',
right: '5mm',
bottom: '5mm',
left: '5mm'
}
})
}
} catch (e) {
console.error(e)
} finally {
// await browser.close()
}
})();
4. 获取 dom 中的数据
// 在页面内执行 document.querySelector。
page.$(selector)
// 在页面内执行 document.querySelectorAll。
page.$$(selector)
// page.$
// page.$$
// page.evaluate
const pageData = await page.evaluate(() => {
// 获取节点容器
const items = Array.from(document.querySelectorAll('#id li'));
// 获取dom 文字信息
return items.map(item => {
return (
{
title: item.querySelector('.xxx a').innerText.replaceAll('/', '//'),
}
)
});
});
5. 简易反反爬虫
1. 动态设置 user-agent
page.setUserAgent(userAgent);
2. 读取 cookie 和设置 cookie
const cookies = await page.cookies()
await page.setCookie(...cookies)
3. 开启存储用户数据,登录一次,未过期时间内,下次自动登录
const browser = await puppeteer.launch({
userDataDir: './userData',
})