Nodejs puppeteer 模拟点击无限循环的问题。
Nodejs puppeteer 模拟点击无限循环的问题。
代码如下,功能是抓取 jandan 段子区的段子吐槽。由于段子的吐槽是分页的,会有个“点击加载更多”的按钮,要判断该按钮是否存在,存在则持续点击。遇到的问题是,要判断按钮是否存在,要用到 document 对象,但 document 对象只存在于page.evaluate()
内;而如果放在page.evaluate()
里判断按钮是否存在,存在则点击,点击要用到page.click(selector)
,而page
对象是又不存在于page.evaluate()
里,该怎么处理?
PS: 案例用了 jandan,如果冒犯到站长或者蛋友,还请包涵,只是测试不做他用。
const puppeteer = require('puppeteer');
const chalk = require('chalk');
(async() => {
const browser = await puppeteer.launch({
executablePath: ‘/Applications/Chromium.app/Contents/MacOS/Chromium’,
headless: true,
slowMo: 200,
ignoreHTTPSErrors: true,
timeout: 10000
});
console.log(chalk.green(‘服务正常启动’));
try {
const page = await browser.newPage();
page.on(‘console’, msg => {
if (typeof msg === ‘object’) {
console.dir(msg);
} else {
console.log(chalk.blue(msg));
}
});
// 进入页面
await page.goto('https://jandan.net/duan/page-94#comments');
const commentBtn = '.tucao-btn';
await page.click(commentBtn);
const tucao = '.jandan-tucao';
const tucao_hot = '.tucao-hot';
const tucao_list = '.tucao-list';
const tucao_more = 'div.jandan-tucao-more:not([style])';
await page.waitForSelector(tucao);
const cmts = await page.evaluate( (selector, more) => {
const tucaos = Array.from(document.querySelector(selector).querySelectorAll('.tucao-row'));
return tucaos.map(comment => {
const author = comment.querySelector('.tucao-author').textContent;
const content = comment.querySelector('.tucao-content').textContent.trim();
const oo = comment.querySelector('.tucao-oo').textContent;
const xx = comment.querySelector('.tucao-xx').textContent;
return `${author} oo[${oo}] xx[${xx}]: \n${content}\n`;
});
}, tucao_list, tucao_more);
console.log(cmts.join('\n'));
await browser.close();
console.log(chalk.green('服务正常结束'));
} catch (error) {
console.log(error);
console.log(chalk.red('服务意外终止'));
await browser.close();
} finally {
process.exit(0);
}
})();
await page.goto(‘https://jandan.net/duan/page-94#comments’, {
timeout: 10000,
waitUntil: ‘domcontentloaded’,
});
const commentBtn = ‘.tucao-btn’;
let length = await page.evaluate(commentBtn => {
let btns = document.querySelectorAll(commentBtn);
btns.forEach(el => el.click());
return btns.length;
}, commentBtn);
console.log(length);
你这是对每一条段子都点击吐槽按钮,和我帖子里的需求不是一回事啊。我是点击第一个吐槽按钮,如果吐槽条数很多会分页,希望把加载更多都点过后再解析。
在Node.js中使用Puppeteer进行模拟点击并实现无限循环,需要注意几个方面,包括页面加载、元素选择、点击事件的触发以及循环控制。以下是一个简单的示例代码,演示如何使用Puppeteer实现模拟点击的无限循环:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless: false}); // 非headless模式方便观察
const page = await browser.newPage();
await page.goto('https://example.com'); // 替换为目标网站
const clickElementSelector = '#someButton'; // 替换为目标按钮的选择器
async function clickElement() {
await page.waitForSelector(clickElementSelector); // 等待元素加载
await page.click(clickElementSelector); // 点击元素
}
// 使用setInterval实现无限循环点击
const clickInterval = setInterval(clickElement, 3000); // 每3秒点击一次
// 可选:设置超时以停止循环(例如,运行10分钟后停止)
setTimeout(() => {
clearInterval(clickInterval);
browser.close();
}, 10 * 60 * 1000);
})().catch(err => console.error(err));
注意事项:
- 确保选择器正确无误,以避免因找不到元素而导致的错误。
headless: false
设置为非headless模式,方便观察浏览器操作,但在生产环境中建议设置为true
以提高效率。- 使用
setInterval
实现循环点击,并通过setTimeout
设置超时以避免无限循环(可选)。
根据实际需求调整选择器、URL、点击间隔及超时时间。