puppeteer 模拟点击无限循环的问题。

2018-04-20 16:46:29 +08:00
 xuyl

代码如下,功能是抓取 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);
    }
})();
5965 次点击
所在节点    Node.js
3 条回复
xuyl
2018-04-20 16:54:23 +08:00
```
while ( document.querySelector(tucao_more) )
{
page.click(tucao_more);
page.waitFor(1000);
}
```
就是这段代码放哪里的问题
dd0754
2018-04-20 21:13:41 +08:00
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);
xuyl
2018-04-20 22:33:06 +08:00
@dd0754 你这是对每一条段子都点击吐槽按钮,和我帖子里的需求不是一回事啊。我是点击第一个吐槽按钮,如果吐槽条数很多会分页,希望把加载更多都点过后再解析。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/448499

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX