Puppeteer 相关介绍与安装不过多介绍,可经过如下连接进行学习javascript
首先,了解下咱们的需求: 爬取 zoomcharts 文档中 Net Chart
目录下全部访问链接对应的页面,并保存到本地html
首先,咱们得研究透 ZoomCharts 页面如何加载,以及左侧导航的 DOM 树结构,才好进行下一步操做前端
页面首次加载 java
Introduction
高亮,从控制台可看出,该元素增长了 active
类,同时 li[data-section="net-chart"]
节点下只有一个元素节点 a
点击 Net Chart
目录node
点击 Net Chart
目录, Net Chart
目录高亮,下拉显示子目录,查看控制台,其元素节点增长 active
类,并增长 ul
子元素节点, 此时,第一个子目录节点也只有一个子元素节点 a
git
不难发现, 左侧目录是动态生成的,而不是静态写死的,只有点击父级目录,其子目录才会生成显示,同时,父级目录元素上的 drop
类代表存在子级目录github
经过上面分析,得出大概流程以下npm
Net Chart
目录的 DOM 树,当找到 a.drop
的元素节点,模拟鼠标点击事件 click
,生成子目录节点Net Chart
目录下全部的 a
连接,生成一个数组接下来实现每一个具体流程数组
安装 puppeteer
, rimraf
(文件夹操做时需用到)bash
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文件
img
时,下载全部图片第一次使用Puppeteer
也是磕磕绊绊,花费很多时间,期间也参考了很多文章,还需多多练习
代码仓库
参考文章