国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Puppeteer 爬取動態生成的網頁實戰

2019-11-19 12:31:29
字體:
來源:轉載
供稿:網友

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

代碼倉庫

代碼倉庫

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 德惠市| 山东省| 南投市| 呼玛县| 舟曲县| 多伦县| 晴隆县| 广南县| 涞水县| 闽侯县| 海阳市| 威远县| 吴旗县| 沂源县| 柯坪县| 双峰县| 湖州市| 永福县| 武宣县| 兴隆县| 嘉荫县| 邛崃市| 高邑县| 哈巴河县| 昌邑市| 平湖市| 石楼县| 桃江县| 彭州市| 东方市| 大庆市| 蓝田县| 明水县| 兴仁县| 新河县| 吉安县| 肇源县| 治多县| 清涧县| 溆浦县| 九江县|