Puppeteer 爬取动态生成的网页实战

Puppeteer 相关介绍与安装不过多介绍,可通过以下链接进行学习

一、Puppeteer

开源地址

英文文档

中文社区

二、爬取动态网页

1. 需求

首先,了解下我们的需求: 爬取zoomcharts文档中 Net Chart 目录下所有访问连接对应的页面,并保存到本地

2. 研究 ZoomCharts 文档页面结构

首先,我们得研究透 ZoomCharts 页面如何加载,以及左侧导航的 DOM 树结构,才好进行下一步操作

页面首次加载

页面首次加载,左侧导航第一个目录 Introduction 高亮,从控制台可看出,该元素增加了 active 类,同时 li[data-section="net-chart"] 节点下只有一个元素节点 a

点击 Net Chart 目录

点击 Net Chart 目录, Net Chart 目录高亮,下拉显示子目录,查看控制台,其元素节点增加 active 类,并增加 ul 子元素节点, 此时,第一个子目录节点也只有一个子元素节点 a

结论

不难发现, 左侧目录是动态生成的,而不是静态写死的,只有点击父级目录,其子目录才会生成显示,同时,父级目录元素上的 drop 类表明存在子级目录

3. 编写主程序

通过上面分析,得出大概流程如下

  • 从上到下,遍历 Net Chart 目录的 DOM 树,当找到 a.drop 的元素节点,模拟鼠标点击事件 click ,生成子目录节点
  • 找到 Net Chart 目录下所有的 a 链接,生成一个数组
  • 遍历数组,访问每一个子目录页面,保存页面的 html 文件到本地

接下来实现每个具体流程

项目初始化

安装 puppeteer , rimraf (文件夹操作时需用到)

npm i -S puppeteer rimraf

新建 test.js 文件并引入

const puppeteer = require('puppeteer');
const chalk = require('chalk');
const path = require('path');
const https = require('https');
const fs = require('fs');
const rm = require('rimraf');

const settings = {
 headless: false
}

function resolve(dir, dir2 = '') {
	return path.posix.join(__dirname, './', dir, dir2);
}

async function main () {
 const browser = await puppeteer.launch(settings); // 创建一个Browser 对象
 try {
  const page = await browser.newPage(); // 使用 Browser 创建 Page
  page.setDefaultNavigationTimeout(600000);
  // 监听 console
  page.on('console', msg => {
   for (let i = 0; i < msg.args().length; ++i) {
    console.log(`${i}: ${msg.args()[i]}`);
   }
  });

  <!-- main start -->
  // main 区域

  <!-- end start-->
  console.log('服务正常结束')
 } catch (error) {
  console.log('服务出现错误:')
  console.log(error)
 } finally {

 }
}

main()

接下来所有代码都在 main 区域内完成, 完整代码可访问github代码仓库 查看,下面仅列出每部分的思路

创建文件夹,用于保存爬取的文件

  • 定义文件输出路径
  • 根据路径生成文件夹
  • 当文件夹已经存在,先删除,再新建

实现 Net Chart 目录下所有 a.drop 元素的点击事件

这部分涉及到DOM 操作, 只有在 page.evaluate() 中才能访问真实的 DOM 元素,同时,在 page.evaluate() 中不能直接调用外面定义的函数,可将函数传递进去,或将函数绑定到 window 对象上

await page.evaluate(async () => {
 const rootNode = document.querySelector('#menu > ul > li:nth-child(5) > ul > li:nth-child(5)');
 await window.walkDOM(rootNode)
})

此时,绑定到 window 对象上的 walkDOM 函数需要在 page.evaluateOnNewDocument 函数中定义才能生效

await page.evaluateOnNewDocument(() => {
 // 遍历DOM
 window.walkDOM = (node) => {
  if (node === null) {
   return
  }
  if (node.tagName === 'A' && node.className.indexOf('drop') > -1) {
   node.click() // 点击事件
  }
  node = node.firstElementChild
  while (node) {
   walkDOM(node)
   node = node.nextElementSibling
  }
 }
})

当Net Chart 目录下所有 a.drop 元素点击过后, Net Chart 目录下所有后代子目录都会加载生成,接下来操作就简单了

获取Net Chart 目录下所有 a 元素

  • 通过 document.querySelectorAll() 查找到所有 a 元素,保存到数组
  • 遍历数组,对数组每一项进行处理成 {href: '',text: ''} 对象
  • 返回对象数组

遍历对象数组, 访问每一个链接,下载其HTML文件

  • 跳转每一个链接,下载需要的html到指定文件夹
  • 当 HTML 中存在 img 时,下载所有图片

4. 总结

第一次使用Puppeteer也是磕磕绊绊,花费不少时间,期间也参考了不少文章,还需多多练习

代码仓库

代码仓库

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Node Puppeteer图像识别实现百度指数爬虫的示例

    之前看过一篇脑洞大开的文章,介绍了各个大厂的前端反爬虫技巧,但也正如此文所说,没有100%的反爬虫方法,本文介绍一种简单的方法,来绕过所有这些前端反爬虫手段. 下面的代码以百度指数为例,代码已经封装成一个百度指数爬虫node库: https://github.com/Coffcer/baidu-index-spider note: 请勿滥用爬虫给他人添麻烦 百度指数的反爬虫策略 观察百度指数的界面,指数数据是一个趋势图,当鼠标悬浮在某一天的时候,会触发两个请求,将结果显示在悬浮框里面: 按照常规

  • node puppeteer(headless chrome)实现网站登录

    puppeteer简介 puppeteer是Chrome团队开发的一个node库,可以通过api来控制浏览器的行为,比如点击,跳转,刷新,在控制台执行js脚本等等.有了这个神器,写个爬虫,自动签到,网页截图,生成pdf,自动化测试什么的,都不在话下. puppeteer的简单例子 代码来自官网: const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch();//打开浏

  • Puppet的一些技巧

    其实很简单,puppet agent只要知道puppet是什么就可以了 你可以将"puppet"写在/etc/hosts里,比如: 127.0.0.1 puppet 这样就不必在puppet.conf中指定server=127.0.0.1了 你还可以给主机改名称,比如: hostnamectl set-hostname x.y.com 然后给你的puppet server一个A记录,注意这个A记录必须也是y.com的子域名 所以它的A记录应该是puppet.y.com 这样你什么都不用

  • 详解Puppeteer 入门教程

    1.Puppeteer 简介 Puppeteer 是一个node库,他提供了一组用来操纵Chrome的API, 通俗来说就是一个 headless chrome浏览器 (当然你也可以配置成有UI的,默认是没有的).既然是浏览器,那么我们手工可以在浏览器上做的事情 Puppeteer 都能胜任, 另外,Puppeteer 翻译成中文是"木偶"意思,所以听名字就知道,操纵起来很方便,你可以很方便的操纵她去实现: 1) 生成网页截图或者 PDF 2) 高级爬虫,可以爬取大量异步渲染内容的网页

  • 如何使用puppet替换文件中的string

    puppet puppet是一种Linux.Unix.windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件.用户.cron任务.软件包.系统服务等.puppet把这些系统实体称之为资源,puppet的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系. puppet采用C/S星状的结构,所有的客户端和一个或几个服务器交互.每个客户端周期的(默认半个小时)向服务器发送请求,获得其最新的配置信息,保证和该配置信息同步.每个puppet客户端每半小时(可以设置)

  • 使用puppeteer破解极验的滑动验证码

    基本的流程: 1. 打开前端网,点击登录. 2. 填写账号,密码. 3. 点解验证按钮,通过滑动验证,最后成功登陆. 代码实现: github上可以checkout. 具体代码如下所示: run.js const puppeteer = require('puppeteer'); const devices = require('puppeteer/DeviceDescriptors'); const iPhone = devices['iPhone 6 Plus']; let timeout

  • 手动下载Chrome并解决puppeteer无法使用问题

    因为网络原因,国内安装 puppeteer 的时候会报网络超时.这里使用 puppeteer-core 之后使用手动下载的 Chrome 进行操作.思路很简单,安装一个不带浏览器的 puppeteer ,再使用的时候将浏览器地址指向一个可执行的 Chrome 浏览器文件. 安装 安装 puppeteer-core . yarn add puppeteer-core 找到 puppeteer 中对应的浏览器并下载 在 node_modules/puppeteer-core/lib/BrowserF

  • node基于puppeteer模拟登录抓取页面的实现

    关于热图 在网站分析行业中,网站热图能够很好的反应用户在网站的操作行为,具体分析用户的喜好,对网站进行针对性的优化,一个热图的例子(来源于ptengine) 上图中能很清晰的看到用户关注点在那,我们不关注产品中热图的功能如何,本篇文章就热图的实现做一下简单的分析和总结. 热图主流的实现方式 一般实现热图显示需要经过如下阶段: 1.获取网站页面 2.获取经过处理后的用户数据 3.绘制热图  本篇主要聚焦于阶段1来详细的介绍一下主流的在热图中获取网站页面的实现方式 4.使用iframe直接嵌入用户网

  • 详解Node使用Puppeteer完成一次复杂的爬虫

    本文介绍了详解Node使用Puppeteer完成一次复杂的爬虫,分享给大家,具体如下: 架构图 Puppeteer架构图 Puppeteer 通过 devTools 与 browser 通信 Browser 一个可以拥有多个页面的浏览器(chroium)实例 Page 至少含有一个 Frame 的页面 Frame 至少还有一个用于执行 javascript 的执行环境,也可以拓展多个执行环境 前言 最近想要入手一台台式机,笔记本的i5在打开网页和vsc的时候有明显卡顿的情况,因此打算配1台 i7

  • Puppeteer环境搭建的详细步骤

    简介 Puppeteer是Google开发并开源的一款工具,可用代码驱动浏览器操作. 由于诸多优秀的特性,Puppeteer常被用在爬虫与自动化测试上.详细介绍参见官方 README. Puppeteer本身是个NodeJS的库,自动化脚本也需要使用NodeJS编写,如果对JS不了解建议先学习JavaScript基础语法,或者使用Selenium等其他工具去实现. 对于一个陌生的工具,应当先检查是否适合自己,再去尝试使用,切莫盲目从众. Puppeteer 用处 利用网页生成PDF.图片 爬取S

随机推荐