51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

nodejs爬虫框架puppeteer的用法

# nodejs爬虫框架puppeteer的用法 {#nodejs爬虫框架puppeteer的用法}

本文讲解爬虫框架puppeteer的基本用法。puppeteer是一个基于nodejs开发的一套爬虫框架,由谷歌开源, 支持headless无头浏览器,与其它同类型(支持headless)的爬虫框架相比,该框架的功能更加强大,可以通过"拦截网络请求"来实现数据的爬取。

# 1. 示例 {#_1-示例}

在此提供一个示例。
实现的功能: 通过程序启动chrome浏览器,然后人为输入账号信息完成登录,切换到广告列表页面,然后程序会自动定时刷新页面,通过拦截接口请求来爬取数据, 然后通过分析接口数据来做进一步的监控报警等工作,达到实现双手的目的。

const puppeteer = require("puppeteer-core");
let browser;
let browserPage;

(async () => {
    try {
        browser = await puppeteer.launch({
            args: ['--no-sandbox', '--disable-setuid-sandbox'],
            executablePath: "C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe",
            headless: false
        });
        browserPage = await browser.newPage();

        // 设置请求拦截器
        await browserPage.setRequestInterception(true);
        getResponseMsg(browserPage);

        // await crawGameList();
        await browserPage.goto("https://channel.xingchenjia.com/#/pch5/codemanage", {timeout: 120000});
        console.log("waiting for login");
        await sleep(30000);
        console.log("finish login");

        while(1){
            try {
                // 点击"禁用tab"页
                let queryBtnSelector = "div#tab-d";
                await browserPage.waitForSelector(queryBtnSelector);
                await browserPage.click(queryBtnSelector);
                console.log("query ad list", formatDate(new Date().getTime()));

                //遍历点击所有页码
                let maxPageCount = 10;
                totalCountRecentOneHour = 0;
                for(let i = 1; i <= maxPageCount; i++){
                    console.log("list all page, latestAdCurrentPage:", i, latestAdCurrentPage.updatetime);
                    try {
                        await browserPage.click("ul.el-pager li:nth-child("+ i +")");
                    } catch (error) {
                        console.log("click current page err", i, error);
                    }
                    await sleep(5000);
                }

                // 更新全局的globalLatestAd
                updateGlobalLatestOne();
                
                // 睡眠60分钟
                await sleep(3600000);
            } catch (error) {
                console.log("exception1", error);
            }
        }

    } catch (e) {
        console.error("exception2", e)
    } finally {
        if (browser != null){
            browser.close();
        }
    }
})();

/**
 * 
 * @param {拦截http请求} page 
 */
async function getResponseMsg(page) {
    return new Promise((resolve, reject) => {
        page.on('request', request => {
            console.log("拦截到http请求", request.url())
            request.continue();
        });

        page.on('response', response => {
            console.log("拦截到http请求的响应", response.url());
            if (response.url() == 'https://channel.xingchenjia.com/v2/media/clientadlist') {
                let message = response.text();
                message.then(function (responseResult) {
                    let responseJson = JSON.parse(responseResult);
                    console.log("http请求的返回数据为", responseJson.data)
                    resolve(responseResult);
                });
            }
        });
    }).catch(new Function()).then();
}

# 2. puppeteer包的选择 {#_2-puppeteer包的选择}

项目的依赖包选择puppeteer或puppeteer-core都可以,两者的关系为puppeteer = puppeteer-core + chrome浏览器,但是推荐使用puppeteer-core,因为这样依赖的体积相对小一些,加快依赖的安装速度。

  • puppeteer
    相当于安装了puppeteer-core,并额外安装一个chrome浏览器,不仅增加了依赖包的体积,也影响依赖的安装速度。
    若机器上之前没有安装过chrome浏览器,那么可以采用该方案,否则建议采用方案puppeteer-core。
    引用方式如下:

    const puppeteer = require("puppeteer");

  • puppeteer-core 若本地已经安装过chrome浏览器,那么强烈建议采用该方案,这样就减少了依赖包的体积,也提升了依赖的安装速度。
    引用方式如下:

    const puppeteer = require("puppeteer-core");

如上所示,选用不同的方案,开头的require方式有所区别, 需要指定不同的名称。

# 3. 脚手架 {#_3-脚手架}

可以基于我的开源项目spider_puppeteer (opens new window)作为脚手架来开发,代码质量不太好,见谅!

赞(3)
未经允许不得转载:工具盒子 » nodejs爬虫框架puppeteer的用法