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 鏈接,生成一個數組接下來實現每個具體流程
項目初始化
安裝 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文件
4. 總結
第一次使用Puppeteer也是磕磕絆絆,花費不少時間,期間也參考了不少文章,還需多多練習
代碼倉庫
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。
新聞熱點
疑難解答