栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Puppeteer 使用

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Puppeteer 使用

Puppeteer 概念:

headless browser(无头浏览器):

是一种在无界面的环境中运行浏览器,与正常浏览器的区别

直接通过命令行或者程序语言操作没有界面,少了加载 css/js、渲染页面的工作,比真实浏览器更快,更稳定

Puppeteer: 是 Chrome 开发团队在 2017 年发布的一个 Node.js 包,用来模拟 Chrome 浏览器的运行

Selenium: 2004年就发布了,支持多种浏览器,多编程语言

Puppeteer & Selenium 对比

功能:

网页截图或者生成 PDF爬取 SPA 或 SSR 网站UI 自动化测试,模拟表单提交,键盘输入,点击等行为捕获网站的时间线,帮助诊断性能问题创建一个最新的自动化测试环境,使用最新的 js 和最新的 Chrome 浏览器运行测试用例测试 Chrome 扩展程序 实例:

截图 或 生成PDF。

const puppeteer = require('puppeteer');

(async () => {
    // 生成browser实例
    const browser = await puppeteer.launch();
    // 调出界面配置
    // const browserConfig = {
    //     headless: false
    // };
    // const browser = await puppeteer.launch(browserConfig);

    // 解析一个新的页面。页面是在默认浏览器上下文创建的
    const page = await browser.newPage();
    await page.setViewport({ width: 1000, height: 500 });
    await page.goto('https://www.jianshu.com/p/c269277ca2d4');

    // 生成图片
    await page.screenshot({ path: 'images/example.png' });

    // 生成pdf
    await page.pdf({ path: 'page.pdf' });

    // 截全屏
    await page.screenshot({
        path: 'images/homepage.png',
        fullPage: true
    })

    // 截取对应选择器部分
    await page.goto('https://www.baidu.com');
    let clip = await page.evaluate(() => {
        let {
            x,
            y,
            width,
            height
        } = document.getElementById('form').getBoundingClientRect();
        return {
            x,
            y,
            width,
            height
        };
    });

    await page.screenshot({
        path: 'images/baidu.png',
        clip: clip //设置clip 属性
    });

    await browser.close();
})();

生成页面 或 爬虫

// 生成页面
const Koa = require('koa');
const fs = require('fs');
const puppeteer = require('puppeteer');

const app = new Koa();
const baseUrl = 'http://www.baidu.com';//这里是真实SPA页面的地址
app.use(async (ctx, next) => {

    let browser = await puppeteer.launch({ dumpio: true, args: ['--no-sandbox', '--disable-setuid-sandbox'], timeout: 10000 });

    const page = await browser.newPage();
    try {

        let myUrl = baseUrl + ctx.url;
        await page.goto(myUrl); //到指定页面的网址.
        await page.waitFor(5000);
    } catch (err) {

        await page.close();
        await browser.disconnect();
        console.log('出现错误:' + err); // 这里捕捉到错误 `error`
    }
    let html = await page.content()

    ctx.type = "text/html;charset=utf-8";
    ctx.body = html.replace('', 'Puppeteer test');
    await page.close();
    await browser.close();

});

app.listen('3388');
console.log('3388端口爬虫代理程序已启动');
const puppeteer = require("puppeteer");
const fs = require("fs");
const path = require("path");

const getNewList = async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto("http://news.baidu.com/");

    //等待“国内”导航按钮出现
    await page.waitForSelector("#channel-all > div > ul > li:nth-child(3) > a");
    //点击“国内”导航按钮,进入国内新闻页面
    await page.click("#channel-all > div > ul > li:nth-child(3) > a");
    //等待“即时新闻列表”出现
    await page.waitForSelector("#instant-news > ul");
    //通过evaluate函数执行自定义的js代码获取要爬取的数据
    const newList = await page.evaluate(() => {
        //创建一个空数组接收爬取的数据
        let data = [];
        //获取所有即时新闻列表li元素
        const elements = document.querySelectorAll("#instant-news > ul > li");
        //利用循环将即时新闻列表的标题和链接地址添加到一个数组中
        for (let i = 0; i < elements.length; i++) {
            //获取新闻的标签
            let title = elements[i].innerText;
            //获取新闻的链接地址
            let url = elements[i].firstChild.getAttribute('href');
            //将获取到的标题和链接地址添加到数组中
            data.push({
                title,
                url
            });
        }
        //返回数组
        return data;
    });
    //关闭浏览器实例
    await browser.close();
    //返回爬取的数据
    return newList;
}
//执行函数获取爬取的数据
getNewList().then(res => {
    //将爬取的数据转为json格式
    let list = JSON.stringify(res);
    //指定存储数据的json文件
    let file = path.join(__dirname, "newList.json");
    //将爬取的数据写入json文件
    fs.writeFile(file, list, err => {
        if (err) {
            console.log(err);
        } else {
            console.log("success");
        }
    })
})

自动提交表单,进行 UI 测试,键盘输入等。

const puppeteer = require("puppeteer");
(async () => {
    const browser = await puppeteer.launch({
        slowMo: 100,    //放慢速度
        headless: false,
        defaultViewport: { width: 1440, height: 780 },
        ignoreHTTPSErrors: false, //忽略 https 报错
        args: ['--start-fullscreen'] //全屏打开页面
    });
    const page = await browser.newPage();
    await page.goto('https://www.baidu.com');
    const element = await page.$('#kw');
    await element.type('Puppeteer', { delay: 20 });

    const okButtonElement = await page.$('#su');
    //等待页面跳转完成,一般点击某个按钮需要跳转时,都需要等待 page.waitForNavigation() 执行完毕才表示跳转成功
    await Promise.all([
        okButtonElement.click(),
        page.waitForNavigation()
    ]);
    // await page.close();
    // await browser.close();
})();

拦截请求

const puppeteer = require("puppeteer");
(async () => {
    const browser = await puppeteer.launch({
        headless: false,
    });
    const page = await browser.newPage();
    const blockTypes = new Set(['image', 'media', 'font']);
    await page.setRequestInterception(true); //开启请求拦截
    page.on('request', request => {
        const type = request.resourceType();
        const shouldBlock = blockTypes.has(type);
        if (shouldBlock) {
            //直接阻止请求
            return request.abort();
        } else {
            //对请求重写
            return request.continue({
                //可以对 url,method,postData,headers 进行覆盖
                headers: Object.assign({}, request.headers(), {
                    'puppeteer-test': 'true'
                })
            });
        }
    });
    await page.goto('https://www.baidu.com');
})();

注入脚本

const puppeteer = require('puppeteer');
(async () => {
    const browser = await puppeteer.launch({ headless: false });
    const page = await browser.newPage();
    await page.goto('https://www.baidu.com');
    await page.addscriptTag({ url: 'https://code.jquery.com/jquery-3.2.1.min.js' });
    // await page.close();
    // await browser.close();
})();

捕获网站的 timeline trace,用来帮助分析性能问题。

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    // 开始跟踪
    await page.tracing.start({ path: 'trace.json' });

    await page.goto('https://www.baidu.com');
    await page.waitForSelector('title');

    // 结束跟踪
    await page.tracing.stop();

    // 各种加载时间
    const loadMetrics = await page.evaluate(() => JSON.stringify(window.performance));
    console.info(JSON.parse(loadMetrics));

    // 运行时间 Performance.getMetrics
    const metrics = await page.metrics();
    console.info('运行时间>>>', metrics);



    await browser.close();
})();

跟踪文件可以在 chrome://tracing 中打开分析

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/739473.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号