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
也是磕磕絆絆,花費很多時間,期間也參考了很多文章,還需多多練習
代碼倉庫
參考文章