Node.js操作Dom ,輕鬆hold住簡單爬蟲

凌覽發表於2023-01-08

前言

前段時間,我發現一個開源題庫,題目非常有意思。我想把它整成一個JSON檔案做為資料儲備,方便整活。

一共有一百五十多道題目,手動CV我肯定是不想幹的。於是寫了個指令碼,在寫指令碼的過程中,我發現一個能讓Node.js操作Dom的開源專案

有了它,再加上jQuery就可以應對簡單爬蟲抓取資料了,所以寫下這篇文章跟大家分享下。

原始碼倉庫地址:CatsAndMice/auto-script (github.com)

解析markdown檔案獲取資料

  • 讀取markdown檔案,去除無用的開頭內容

const readMd = (path) => {
    let content = fs.readFileSync(path, { encoding: 'utf-8' });
    content = content.split('---');
    // 去除開頭無用開頭內容
    content.shift(0, 1);
    return content;
}

markdown檔案中每一段內容都是—-分隔,那就直接以它來分割檔案內容為若干塊,第一塊為開頭內容content.shift(0, 1)去除掉

  • 使用markdown-it將markdown內容渲染成html內容,這個時候的html僅僅是字串,jsDom將html字串轉化成Dom
const mdIt = require('markdown-it')();
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
//...
const parseMd = (md = '') => {
    const mdHtml = mdIt.render(md)
    const dom = new JSDOM(mdHtml)
    const { window } = dom
    return window
}
//...

完成markdown渲染成html字串,html字串轉化成Dom後,直接把window這個變數返回出去即可。

  • 引入jQuery操作Dom
const getMdMapValue = (mds = []) => {
    const mdMap = new Map();
    mds.forEach((md, index) => {
        const id = index + 1
        const window = parseMd(md)
        const $ = require('jquery')(window);
        //...
    })
    return Array.from(mdMap.values())
}
  • 接下來,即使用$ 針對性的獲取Dom內容
const getMdMapValue = (mds = []) => {
    const mdMap = new Map();
    mds.forEach((md, index) => {
        const id = index + 1
        const window = parseMd(md)
        const $ = require('jquery')(window);
        
        //新增
        const answer = parseAnswer($('p'))
        const obj = { id, title: $('h6').text(), result: $('h4').text(), code: $('.language-javascript').text(), answer }
        // 如果選項解析失敗,則拋棄該題目
        try {
            parseSelect($('ul>li'), (key, value) => {
                const option = { key, value }
                if (obj.options) {
                    obj.options.push(option)
                    return
                }
                obj.options = [option]
            })
            mdMap.set(id, obj)
        } catch (error) {
            console.warn('解析出錯:', error)
        }
        
       
    })
    return Array.from(mdMap.values())
}

其他的邏輯就是將<code>、<em>等標籤轉化成`、**等markdown符號相關邊界性問題處理,不詳細貼上程式碼,讀者可以檢視原始碼

寫個小爬蟲

我選擇爬取https://fabiaoqing.com/bqb/li... 網站的表情圖,邏輯非常簡單,幾十行搞定。

還是使用jsDom將請求響應的html檔案內容轉化為Dom,再使用jQuery操作。

crawl.js

const axios = require('axios');
const { JSDOM } = require('jsdom');
let $ = require('jquery');
const fs = require('fs');
const path = require('path');

(async () => {
    const { data } = await axios.get('https://fabiaoqing.com/bqb/lists/type/hot.html')
    const page = new JSDOM(data)
    const window = page.window
    $ = $(window)
    $('.bqppdiv').each(async (index, e) => {
        const src = $(e).find('.image')[0].getAttribute('data-original')
        const type = path.extname(src)
        const fileName = Date.now() + type
        const { data } = await axios.get(src, {responseType: 'stream'})
        const download = path.join(__dirname, fileName)
        data.pipe(fs.createWriteStream(download))
    })
})()

這裡,我僅演示下爬蟲不再深入,類似簡單爬蟲僅使用jquery、jsDom即可搞定,不需要學習其他複雜的爬蟲工具。

總結

透過解析markdown檔案將純markdown文字解析成html字串,又將html字串轉化成真實的Dom物件,再使用jQuery來獲取Dom,達成markdown檔案內資訊轉成JSON檔案作為資料儲存的目的,最後演示NodeJs操作Dom,並簡單寫一個爬蟲做為練習。

如果我的文章對你有幫助,你的?就是對我的最大支援^_^,另外歡迎大家關注我的公眾號《凌覽社》,和我一起成長。

本文由mdnice多平臺釋出

相關文章