视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Puppeteer环境搭建的详细步骤
2020-11-27 22:07:18 责编:小采
文档

Puppeteer 用处

  • 利用网页生成PDF、图片
  • 爬取SPA应用,并生成预渲染内容(即“SSR” 服务端渲染)
  • 可以从网站抓取内容
  • 自动化表单提交、UI测试、键盘输入等
  • 帮你创建一个最新的自动化测试环境(chrome),可以直接在此运行测试用例6.捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题
  • 配置

    Node环境配置

    下载并安装NodeJS:

    wget https://nodejs.org/dist/v8.12.0/node-v8.12.0-linux-x.tar.xz
    tar xf node-v8.12.0-linux-x.tar.xz
    mv node-v8.12.0-linux-x /usr/local/lib
    ln -s /usr/local/lib/node-v8.12.0-linux-x/bin/npm /usr/local/bin/
    ln -s /usr/local/lib/node-v8.12.0-linux-x/bin/node /usr/local/bin/

    *(可选)配置淘宝的源,加速npm包的下载:

    npm config set registry https://registry.npm.taobao.org

    安装Puppeteer

    配置淘宝的Puppeteer下载源,用于安装Chromium:

    export PUPPETEER_DOWNLOAD_HOST=https://storage.googleapis.com.cnpmjs.org
    npm i puppeteer
    

    国内不配置时会在卡在下载Chromium

    示例

    新建一个test.js

    const puppeteer = require('puppeteer');
    
    (async () => {
     const browser = await puppeteer.launch({
     ignoreHTTPSErrors: true,
     headless: false,
     args: ['--no-sandbox']
     });
     const page = await browser.newPage();
     await page.goto('https://intest.tech');
     await page.waitFor(5e3);
     await browser.close();
    })();
    
    

    运行:

    node test.js

    截图

    知识点

  • puppeteer.launch 启动浏览器实例
  • browser.newPage() 创建一个新页面
  • page.goto 进入指定网页
  • page.screenshot 截图
  • const puppeteer = require('puppeteer');
    
    (async () => {
    const browser = await (puppeteer.launch({
    // 若是手动下载的chromium需要指定chromium地址, 默认引用地址为 /项目目录/node_modules/puppeteer/.local-chromium/
    executablePath: '/Users/huqiyang/Documents/project/z/chromium/Chromium.app/Contents/MacOS/Chromium',
    //设置超时时间
    timeout: 15000,
    //如果是访问https页面 此属性会忽略https错误
    ignoreHTTPSErrors: true,
    // 打开开发者工具, 当此值为true时, headless总为false
    devtools: false,
    // 关闭headless模式, 会打开浏览器
    headless: false
    }));
    const page = await browser.newPage();
    await page.goto('https://www.jianshu.com/u/40909ea33e50');
    await page.screenshot({
    path: 'jianshu.png',
    type: 'png',
    // quality: 100, 只对jpg有效
    fullPage: true,
    // 指定区域截图,clip和fullPage两者只能设置一个
    // clip: {
    // x: 0,
    // y: 0,
    // width: 1000,
    // height: 40
    // }
    });
    browser.close();
    })();
    

    进阶,获取网易云音乐的歌词和评论

    网易云音乐的API经过AES和RSA算法加密,需要携带加密的信息通过POST方式请求才能获取到数据。但 Puppeteer 出现后,这些都不重要了,只要它页面上显示了,通过 Puppeteer 都能获取到该元素。

    知识点

  • page.type 获取输入框焦点并输入文字
  • page.keyboard.press 模拟键盘按下某个按键,目前mac上组合键无效为已知bug
  • page.waitFor 页面等待,可以是时间、某个元素、某个函数
  • page.frames() 获取当前页面所有的 iframe,然后根据 iframe 的名字精确获取某个想要的 iframe
  • iframe.$('.srchsongst') 获取 iframe 中的某个元素
  • iframe.evaluate() 在浏览器中执行函数,相当于在控制台中执行函数,返回一个 Promise
  • Array.from 将类数组对象转化为对象
  • page.click() 点击一个元素
  • iframe.$eval() 相当于在 iframe 中运行 document.queryselector 获取指定元素,并将其作为第一个参数传递
  • iframe.$$eval 相当于在 iframe 中运行 document.querySelectorAll 获取指定元素数组,并将其作为第一个参数传递
  • const fs = require('fs');
    const puppeteer = require('puppeteer');
    
    (async () => {
    const browser = await (puppeteer.launch({ executablePath: '/Users/huqiyang/Documents/project/z/chromium/Chromium.app/Contents/MacOS/Chromium', headless: false }));
    const page = await browser.newPage();
    // 进入页面
    await page.goto('https://music.163.com/#');
    
    // 点击搜索框拟人输入 鬼才会想起
    const musicName = '鬼才会想';
    await page.type('.txt.j-flag', musicName, {delay: 0});
    
    // 回车
    await page.keyboard.press('Enter');
    
    // 获取歌曲列表的 iframe
    await page.waitFor(2000);
    let iframe = await page.frames().find(f => f.name() === 'contentFrame');
    const SONG_LS_SELECTOR = await iframe.$('.srchsongst');
    
    // 获取歌曲 鬼才会想起 的地址
    const selectedSongHref = await iframe.evaluate(e => {
    const songList = Array.from(e.childNodes);
    const idx = songList.findIndex(v => v.childNodes[1].innerText.replace(/\s/g, '') === '鬼才会想起');
    return songList[idx].childNodes[1].firstChild.firstChild.firstChild.href;
    }, SONG_LS_SELECTOR);
    
    // 进入歌曲页面
    await page.goto(selectedSongHref);
    
    // 获取歌曲页面嵌套的 iframe
    await page.waitFor(2000);
    iframe = await page.frames().find(f => f.name() === 'contentFrame');
    
    // 点击 展开按钮
    const unfoldButton = await iframe.$('#flag_ctrl');
    await unfoldButton.click();
    
    // 获取歌词
    const LYRIC_SELECTOR = await iframe.$('#lyric-content');
    const lyricCtn = await iframe.evaluate(e => {
    return e.innerText;
    }, LYRIC_SELECTOR);
    
    console.log(lyricCtn);
    
    // 截图
    await page.screenshot({
    path: '歌曲.png',
    fullPage: true,
    });
    
    // 写入文件
    let writerStream = fs.createWriteStream('歌词.txt');
    writerStream.write(lyricCtn, 'UTF8');
    writerStream.end();
    
    // 获取评论数量
    const commentCount = await iframe.$eval('.sub.s-fc3', e => e.innerText);
    console.log(commentCount);
    
    // 获取评论
    const commentList = await iframe.$$eval('.itm', elements => {
    const ctn = elements.map(v => {
    return v.innerText.replace(/\s/g, '');
    });
    return ctn;
    });
    console.log(commentList);
    })();
    

    参考

    https://github.com/cnpm/cnpmjs.org/issues/1246#issuecomment-341631992

    下载本文
    显示全文
    专题