内容简介:Puppeteer 相关介绍与安装不过多介绍,可通过以下链接进行学习首先,了解下我们的需求: 爬取zoomcharts 文档中首先,我们得研究透 ZoomCharts 页面如何加载,以及左侧导航的 DOM 树结构,才好进行下一步操作
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文件
img
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 实战生成对抗网络(二):生成手写数字
- 实战生成对抗网络[2]:生成手写数字
- 实战生成对抗网络(三):DCGAN
- 深度学习实战 numpy生成实数序列
- [项目实战][原创]PHP生成全景图(krpano)
- 用机器学习生成披头士的歌词 | 项目实战
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ACM图灵奖演讲集
阿申豪斯特 / 苏运霖 / 电子工业出版社 / 2005-4 / 55.0
本书完整地收录了这些演讲,并配之以部分获奖者撰写的后记,旨在反映过去数年来这一领域中发生的变化。对任何一位计算机科学的历史与发展有兴趣的人来说,本书都极具收藏价值。 本文收录了自图灵奖开始颁发的1966年起到1985年这20年间图灵奖获得者在授奖大会上所做演讲的全文。由于在此期间有三次是把奖项同时授予两个人的,而其中有两次两位获奖者分别做了演讲,因此一共收录了22篇演讲稿。本书把这些演讲分为两大......一起来看看 《ACM图灵奖演讲集》 这本书的介绍吧!