您现在的位置是:首页 > 正文

Puppeteer万物皆可爬

2024-04-01 04:44:44阅读 2

puppeteer 是一个Chrome官方出品的headless Chrome node库。它提供了一系列的API, 可以在无UI的情况下调用Chrome的功能, 适用于爬虫、自动化处理等各种场景

puppteer

puppeteer 是一个Chrome官方出品的headless Chrome node库(没有图形用户界面的的web浏览器)。它提供了一系列的API, 可以在无UI的情况下调用Chrome的功能, 适用于爬虫、自动化处理等各种场景

可以用它来干什么?

  • 生成页面截图和PDF

  • 自动化表单提交、UI 测试、键盘输入等

  • 创建一个最新的自动化测试环境。使用最新的 JavaScript 和浏览器功能,可以直接在最新版本的 Chrome 中运行测试。

  • 爬取 SPA 页面并进行预渲染(即'SSR')

  • ...

和cheerio的区别

  • cheerio - 这货说白了就是类似jq语法操作的html文档库,只能爬取静态的html,无法获取ajax数据,一般都axios+cherrio结合使用

  • puppteer - 能够模拟浏览器运行环境,能够请求网站信息。能够进行模拟操作(点击/滑动/hover等),甚至能注入node脚本到浏览器内部环境运行

puppteer架构图

  • Puppeteer - 通过 devTools 与 browser 通信

  • Browser -  一个可以拥有多个页面的浏览器(chroium)实例

  • Page -  至少含有一个 Frame 的页面

  • Frame -  至少还有一个用于执行 javascript 的执行环境,也可以拓展多个执行环境

轻松入门

const puppeteer = require('puppeteer');(async () => {  const browser = await puppeteer.launch();  const page = await browser.newPage();  await page.goto(targetUrl);  await page.screenshot({path: 'example.png'});  await browser.close();})();

分析代码

1.引入puppeteer

const puppeteer = require('puppeteer');

2.生成实例

也就是通过Puppeteer启动一个浏览器环境

const browser = await puppeteer.launch(options);

options:

  • executablePath: puppeteer.executablePath() - 获取默认可执行的chrome位置

  • headless: false - 是否开启headless模式

  • slowMo: 250 - 该选项会是puppeteer操作减慢指定的毫秒数

  • devtools: true - 在应用程序代码浏览器中使用调试器

  • defaultViewport(object) - 默认800 x 600

    • width

    • height

    • deviceScaleFactor - 比例因子

    • isMobile - 是否考虑meta viewport 标签, 默认为false

    • hasTouch - 指定viewport是否支持触摸事件,默认为false

    • isLandscape - 指定是否处于横向模式

  • 更多参数请参照Puppeteer.launch()[1]

3.打开一个新页面

const page = await browser.newPage();

4.前往目标页面

await page.goto(targetUrl);

注意:这里可接受第二个参数,是个对象,用来进行一些简单的配置,待选项有

waitUntil:

  • load - 请求到数据后立即返回

  • domcontentloaded - dom加载完成后返回

  • networkidle0 - 没有超过0个网络连接500ms后返回

  • networkidle2 - 没有超过2个网络连接500ms后返回

timeout: 跳转等待时间,单位是毫秒, 默认是30秒, 传 0 表示无限等待,可以通过page.setDefaultNavigationTimeout(timeout)方法修改默认值

referer(不常用): 引用页头的值。如果提供,它将优先于page.setExtraHTTPHeaders()设置的referer头值(Referer header value. If provided it will take preference over the referer header value set by page.setExtraHTTPHeaders().)

5.关闭浏览器

 browser.close();

花里胡哨

其实轻松入门节已经将我们常用的功能进行了相对完善的描述,总结一下,爬一个网页需要几步

  1. 打开浏览器

  2. 关闭浏览器

是不是很简单?问题来了?怎么爬?会不会用jq?会用jq你就会用爬虫。

找到一个自己喜欢的视频网站,(以下内容仅供教学!)

const demo = async () => {  const browser = await (puppeteer.launch({    executablePath: puppeteer.executablePath(),    headless: false  }))  var arr = []  for (let i = 1; i <= 40; i++) {    console.log('正在抓取全职高手第' + i + '集')    const targetUrl = `https://goudaitv1.com/play/78727-4-${i}.html`    console.log(targetUrl)    const page = await browser.newPage()    await page.goto(targetUrl, {      timeout: 0,      waitUntil: 'domcontentloaded'    })    const baseNode = '.row'    const movieList = await page.evaluate((sel) => {      var stream = Array.from($(sel).find('iframe#Player').attr('src'))      stream && (stream = stream.join(''))      return stream    }, baseNode)    arr.push(movieList)    page.close()  }  console.log(arr)  browser.close()}

page.evaluate(pageFunction[, ...args])

  • pageFunction <function|string> 要在页面实例上下文中执行的方法

  • ...args 要传给 pageFunction 的参数

  • 返回:

    pageFunction执行的结果

如果pageFunction返回的是Promise,page.evaluate将等待promise完成,并返回其返回值。

如果pageFunction返回的是不能序列化的值,将返回undefined

给pageFunction传参数示例:

const result = await page.evaluate(x => {  return Promise.resolve(8 * x);}, 7); // (注:7 可以是你自己代码里任意方式得到的值)console.log(result); // 输出 "56"

也可以传入一个字符串

console.log(await page.evaluate('1 + 2')); // 输出 "3"const x = 10;console.log(await page.evaluate(`1 + ${x}`)); // 输出 "11"

存入数据库

搞定!你可以用这些数据做自己想做的一切,比如

最后

当然,'爬'只是它的冰山一角,上述demo比较偷懒的直接获取了标签的地址进行跳转,我们还可以使用点击事件进行页面跳转,感兴趣的可以试试。

page.click(selector[, options])

  • selector  要点击的元素的选择器。如果有多个匹配的元素, 点击第一个。

  • options

    • button  left, right, 或者 middle, 默认是 left。

    • clickCount  默认是 1. 查看 UIEvent.detail。

    • delay  mousedown 和 mouseup 之间停留的时间,单位是毫秒。默认是0

  • 返回:  Promise对象,匹配的元素被点击。如果没有元素被点击,Promise对象将被rejected。

此方法找到一个匹配 selector 选择器的元素,如果需要会把此元素滚动到可视,然后通过 page.mouse 点击它。如果选择器没有匹配任何元素,此方法将会报错。

要注意如果 click() 触发了一个跳转,会有一个独立的 page.waitForNavigation() Promise对象需要等待。正确的等待点击后的跳转是这样的:

const [response] = await Promise.all([  page.waitForNavigation(waitOptions),  page.click(selector, clickOptions),]);
  • page.waitForNavigation([options])

此方法在页面跳转到一个新地址或重新加载时解析,如果你的代码会间接引起页面跳转,这个方法比较有用。

更多参照page.waitForNavigation([options])[2]

参考

Puppeteer 中文网[3]

Puppeteer npm[4]

参考资料

[1]

Puppeteer.launch(): https://github.com/GoogleChrome/puppeteer/blob/v1.20.0/docs/api.md#puppeteerlaunchoptions

[2]

page.waitForNavigation([options]): https://zhaoqize.github.io/puppeteer-api-zh_CN/#?product=Puppeteer&version=v1.20.0&show=api-pagewaitfornavigationoptions

[3]

Puppeteer 中文网: https://zhaoqize.github.io/puppeteer-api-zh_CN/

[4]

Puppeteer npm: https://www.npmjs.com/package/puppeteer

更多

  • 觉得内容有帮助,点个在看~~

  • 欢迎转裁到朋友圈,分享给更多的人看~~

    欢迎关注公众号 「前端Q」,持续学习成长~~


网站文章

  • gin post 数据参数_golang--gin获取post里body的参数

    以下内容转载自https://blog.csdn.net/weixin_36344862/article/details/111932206如题,post发送数据有几种形式,form和流是最常用的。特...

    2024-04-01 04:44:32
  • 前端实现图片下载的方法

    在任何方案下,前端都无法绕过跨域的限制,所以需要图片所在的服务器对你当前域名开放权限,否则是无法下载的,最多能做到查看图片。1、直接使用a标签的download属性。2、canvas对象+a标签。3、ajax请求(blob或base64格式)+a标签。4、domtoimage+a标签。5、form表单。6、iframe。

    2024-04-01 04:43:51
  • mybatis运行原理详解

    mybatis运行原理详解

    第一部分:项目结构user_info表:没什么好说的就3个字段User实体类:@Datapublic class User { private Long id; private Strin...

    2024-04-01 04:43:44
  • Leetcode刷题详解——子集

    Leetcode刷题详解——子集

    在递归时我们需要保证递归结束时当前的状态与进行递归操作前的状态不变,而当我们在选择进行步骤2进行递归时,当前状态会发生变化,因此我们需要在递归结束时撤回添加操作,即进行回溯。数组一定存在2^(数组长度...

    2024-04-01 04:43:36
  • 计算机毕业设计/课程设计系列基于SpringBoot的校园问答论坛管理系统

    计算机毕业设计/课程设计系列基于SpringBoot的校园问答论坛管理系统

    本课程演示的是一款基于SpringBoot的校园问答论坛管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。1. 包含:项目源码、项目文档、数据库脚本、软件工具等...

    2024-04-01 04:43:28
  • DVWA渗透测试演示(中)

    DVWA渗透测试演示(中)

    续DVWA渗透测试演示(上):六、DVWA之FileInclusion:(1)实验原理:PHP文件包含漏洞的产生原因是在通过PHP函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预料之外...

    2024-04-01 04:42:53
  • [计算机网络]应用层协议,HTTP,SMTP,DNS

    [计算机网络]应用层协议,HTTP,SMTP,DNS

    应用层应用层协议原理网络应用程序体系结构规定如何在各种端系统上组织应用程序,由研发者设计客户机/服务器服务器:对外提供服务的一系列硬件和软件客户机:使用服务器提供的服务服务器7*24小时提供服务永久性...

    2024-04-01 04:42:47
  • VS 2005中使用C#创建及调用WebService完整实例

    关于WebService的概念及相关说明,在这里就不多说了,直接说如何实现IIS配置安装IIS(Windows 默认安装即可),确认可以从其他IP访问本机的默认主页,安装ASP.NET 2.0到IIS...

    2024-04-01 04:42:40
  • win10如何调整计算机时间同步,Win10系统如何设置时间同步间隔?修改时间同步频率的方法...

    win10如何调整计算机时间同步,Win10系统如何设置时间同步间隔?修改时间同步频率的方法...

    Win10系统如何设置时间同步间隔?如果系统时间并没有那么精确,偏差很多,你一定会去勾选“自动同步时间”的功能吧?!可是左等右等也不见调整时间,是这项功能没用吗?其实系统时间同步的频率是有间隔的,且这...

    2024-04-01 04:41:58
  • ES集群中节点与分片的区别

    ES集群中节点与分片的区别

    ES集群中节点与分片的区别 一开始我也搞混了,以为分片就是节点 节点:节点就是我们一个个的主机,你也可以理解为一个个的ES 分片:分片就是将原来存放在一个节点上面的数据进行分片,然后存放到不同的节点。...

    2024-04-01 04:41:50