凌览

V1

2023/01/03阅读:23主题:全栈蓝

Node.js操作Dom ,轻松hold住简单爬虫

前言

前段时间,我发现一个开源题库,题目非常有意思。我想把它整成一个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(01);
    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/lists/type/hot.html网站的表情图,逻辑非常简单,几十行搞定。

还是使用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,并简单写一个爬虫做为练习。

如果我的文章对你有帮助,你的👍就是对我的最大支持^_^,另外欢迎大家关注我的公众号《凌览社》,和我一起成长。

分类:

前端

标签:

前端

作者介绍

凌览
V1