// ... 之前的代码
if (page.url() === 'https://example.com/login') {
console.log('检测到需要登录,正在执行登录操作...');
await page.type('#input-email', 'your_email@example.com'); // 替换为实际邮箱
await page.type('#input-password', 'your_password'); // 替换为实际密码
await page.click('.button-primary');
// 关键一步:等待页面导航完成,确保登录成功并跳转到目标页面
await page.waitForNavigation({ waitUntil: 'networkidle0' }); // 推荐等待网络空闲
console.log('登录成功并完成页面导航。');
}
// ... 后续的元素抓取标签的文本内容:
[INFO] 1SkeLt7 joined the game
[INFO] Another user joined
// ... 之前的代码
console.log('开始提取日志元素...');
// 使用 $$eval 高效提取所有匹配 标签的文本内容
const logElements = await page.$$eval('#consoleDiv > div > p', (elements) =>
elements.map((el) => el.textContent.trim()) // 遍历元素,提取文本并去除空白
);
// logElements 现在是一个包含所有
标签文本的数组
if (logElements.length > 0) {
console.log('成功提取到日志信息:');
for (const log of logElements) {
console.log(log);
}
} else {
console.log('未提取到任何日志信息,请检查选择器或页面内容。');
}
// ... 后续操作
元素的数组。回调函数使用 map 方法遍历这些元素,提取它们的 textContent 并使用 trim() 方法去除首尾空白。最终,一个包含所有清理后文本的数组 logElements 会被返回。 4. 完整优化代码示例 将上述两种优化策略整合到一起,可以得到一个更健壮、高效的Puppeteer抓取脚本:
const puppeteer = require('puppeteer');
async function scrapeLog() {
let browser; // 声明浏览器实例变量,以便在 finally 块中关闭
try {
browser = await puppeteer.launch({
headless: true, // 在后台运行浏览器
defaultViewport: null, // 不设置默认视口,使用页面内容决定
userDataDir: "./tmp" // 保存用户数据,例如登录状态、缓存等
});
const page = await browser.newPage();
// 访问目标URL
await page.goto('https://example.com/console', { waitUntil: 'domcontentloaded' }); // 初始页面加载,等待DOM内容加载
// 判断是否需要登录
if (page.url().includes('login')) { // 使用 includes 更通用
console.log('检测到需要登录,正在执行登录操作...');
await page.type('#input-email', 'your_email@example.com'); // 替换为实际邮箱
await page.type('#input-password', 'your_password'); // 替换为实际密码
await page.click('.button-primary');
// 等待页面导航完成,确保登录成功并跳转到目标页面
await page.waitForNavigation({ waitUntil: 'networkidle0' }); // 等待网络空闲
console.log('登录成功并完成页面导航。');
}
// 再次确认当前页面是否为目标页面,以防重定向或登录失败
if (!page.url().includes('console')) {
console.warn('登录后未跳转到预期的控制台页面,尝试再次访问...');
await page.goto('https://example.com/console', { waitUntil: 'networkidle0' });
// 再次检查,如果仍然不是,则可能登录失败或URL不正确
if (!page.url().includes('console')) {
throw new Error('未能成功导航到控制台页面。');
}
}
console.log('开始提取日志元素...');
// 使用 $$eval 高效提取所有匹配 标签的文本内容
const logElements = await page.$$eval('#consoleDiv > div > p', (elements) =>
elements.map((el) => el.textContent.trim())
);
if (logElements.length > 0) {
console.log('成功提取到日志信息:');
for (const log of logElements) {
console.log(log);
}
} else {
console.log('未提取到任何日志信息,请检查选择器或页面内容。');
}
} catch (error) {
console.error('脚本执行出错:', error);
// 在这里可以添加截图、保存HTML等调试信息
if (browser && browser.pages().length > 0) {
const page = (await browser.pages())[0];
await page.screenshot({ path: 'error_screenshot.png' });
console.log('已保存错误截图:error_screenshot.png');
}
} finally {
// 确保在任何情况下都关闭浏览器实例
if (browser) {
await browser.close();
console.log('浏览器已关闭。');
}
}
}
scrapeLog();
