利用nodejs第三方库puppeteer来解决某些用js渲染页面的登陆页模拟登陆问题

利用nodejs第三方库puppeteer来解决某些用js渲染页面的登陆页模拟登陆问题,第1张

利用nodejs第三方库puppeteer来解决某些用js渲染页面的登陆模拟登陆问题

偶然发现一个叫puppeteer的库,这样解释的:“谷歌浏览器在17年自行开发了Chrome Headless特性,并与之同时推出了puppeteer,可以理解成我们日常使用的Chrome的无界面版本以及对其进行 *** 控的js接口套装”。简单说就是模拟浏览器行为的第三方库,再说直白点,只要用浏览器访问的页面,它都可以去 *** 作,强大之至。
想起朋友在做一个学校教务系统爬虫,苦于该校登陆界面是用js渲染的,登陆接口会拼接上js加密的字符串,这个字符串只有在浏览器下才会动态生成,js又是瑞数加密,破解成本极高,极难,便来尝试利用puppeteer来模拟登陆获取用户数据。
现在开始,打开登陆界面开始分析

用puppeteer其实就是人怎么 *** 作的,将它写成代码即可
1:打开网址
2:输入学号
3:输入密码
4:点击登陆
实现成代码便是:

  const puppeteer = require('puppeteer');
  const browser = await puppeteer.launch({
    ignoreDefaultArgs: ["--enable-automation"],
    headless: true,
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  }); //去除自动化测试的提醒

  const page = await browser.newPage();
  //为了像一个浏览器,伪造更多数据
  await page.evaluateOnNewdocument(() => { //在每个新页面打开前执行以下脚本
    const newProto = navigator.__proto__;
    delete newProto.webdriver; //删除navigator.webdriver字段
    navigator.__proto__ = newProto;
    window.chrome = {}; //添加window.chrome字段,为增加真实性还需向内部填充一些值
    window.chrome.app = {
      "InstallState": "hehe",
      "RunningState": "haha",
      "getDetails": "xixi",
      "getIsInstalled": "ohno"
    };
    window.chrome.csi = function () {};
    window.chrome.loadTimes = function () {};
    window.chrome.runtime = function () {};
    Object.defineProperty(navigator, 'userAgent', { //userAgent在无头模式下有headless字样,所以需覆写
      get: () => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36",
    });
    Object.defineProperty(navigator, 'plugins', { //伪装真实的插件信息
      get: () => [{
        "description": "Portable document Format",
        "filename": "internal-pdf-viewer",
        "length": 1,
        "name": "Chrome PDF Plugin"
      }]
    });
    Object.defineProperty(navigator, 'languages', { //添加语言
      get: () => ["zh-CN", "zh", "en"],
    });
    const originalQuery = window.navigator.permissions.query; //notification伪装
    window.navigator.permissions.query = (parameters) => (
      parameters.name === 'notifications' ?
      Promise.resolve({
        state: Notification.permission
      }) :
      originalQuery(parameters)
    );
  })
  await page.goto('http://xxx/Login.html')
  await page.waitForNavigation();//等待加载完成
  await page.type('#txtUser', "20190xxxxx");
  await page.type('#txtPWD', '42052120xxxxx');
  await page.click('#ibtnLogin');
  await page.waitForNavigation();
  


登陆成功,接着点击【成绩单】

  const [response] = await Promise.all([
    page.waitForNavigation(),
    page.click('a[href="SearchInfo/Score/ScoreList.aspx"]')
  ]);
  let res = await page.$eval('ul.listUl', el => el.outerHTML)//拿到dom
  await browser.close();

如果输出res则是这个表格的所有代码

这玩意还可以截屏,没错,你看不到界面,还可以用方法截屏

    await page.screenshot({

        path: 'c:/temp/temp.png'

    })

加上这段就可以截屏并存在C盘下temp文件夹里,如果没有文件夹不会自动创建,需要自己提前创建好

是不是感觉好用到爆,可是这玩意儿就好比后台打开了一个浏览器运行的,如果多个请求进来,后台也会打开多个任务,分别执行,但是并发高了岂不是服务器都要炸了。那能不能放到云函数里呢?答案是可以的。

放到微信小程序云函数中可以直接运行,无需安装库,官方nodejs10版本已经默认安装了,直接引用就可以用

再来看耗时和所占内存大小

耗时2789ms,内存135.74MB完全可以接受。

总结:puppeteer模拟登陆可以做任何形式的网站,但是速度有点慢

优点:最大优点也是优势就是可以做那些做了反爬虫的网站,和js渲染的网站
缺点:内存黑洞,放服务器上不能应对高并发(用云函数可以解决),速度慢,因为是模拟人工 *** 作,输入内容都是一个个值输入,还要等待加载,所以比常规的请求接口方式慢不少

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5689397.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-17
下一篇2022-12-17

发表评论

登录后才能评论

评论列表(0条)

    保存