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

news/2024/11/8 9:37:52/

前言

前段时间,我发现一个开源题库,题目非常有意思。我想把它整成一个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 } = domreturn window
}
//...

完成markdown渲染成html字符串,html字符串转化成Dom后,直接把window这个变量返回出去即可。

  • 引入jQuery操作Dom
const getMdMapValue = (mds = []) => {const mdMap = new Map();mds.forEach((md, index) => {const id = index + 1const 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 + 1const 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() + typeconst { 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,并简单写一个爬虫做为练习。

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


http://www.ppmy.cn/news/9034.html

相关文章

【linux】三种权限的使用和更改、粘滞位和yum的使用

目录 1.权限问题 ①什么是权限&#xff1f; ②小问题 ③默认权限 ④如何更改“人”的权限呢&#xff1f; ⑤更改权限的八进制方案 ⑥强制改权限里的“人”&#xff08;权限人文件属性&#xff09; 2.粘滞位 2.yum的使用 1.权限问题 ①什么是权限&#xff1f; 权限人&a…

“当不存在跨域问题,也解决了数据验证时,还出现:No ‘Access-Control-Allow-Origin‘,说存在跨域问题 ”的解决办法

不存在跨域问题&#xff0c;数据验证也弄好了&#xff0c;还出现下面的问题&#xff1a;Access to XMLHttpRequest at https://m.maizuo.com/gateway?cityId440100&pageNum1&pageSize10&type1&k7325551 from origin http://localhost:8080 has been blocked b…

1231. 航班时间(恶心的输入处理 + 简单的数学)

题目如下&#xff1a; 题解 or 思路&#xff1a; 因为题目假设两次飞行时间是相同的&#xff0c;我们可以通过减法将时差消去。那么飞行时间就是: time1time22\frac{time_1 time2}{2}2time1​time2​ 题目的难点是处理输入&#xff0c;我们可以使用 sscanf 来进行处理&#x…

Vi/Vim模式下常见的命令操作

Vi和Vim的使用 Linux系统内会内置Vi 文本编辑器 vim 具有程序编辑能力&#xff0c;可以看做是vi的增强版本&#xff0c;可以主动以字体颜色辨别语法的正确性&#xff0c;方便程序设计。因此在程序员中被广泛使用 VIM有三种工作模式 一般模式/正常模式插入模式/编辑模式命令…

包装器和绑定器std::bind和std::function的回调技术

回调函数 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另一个函数&#xff0c;当这个指针被用来调用其所指向的函数时&#xff0c;我们就说这是回调函数。回调函数不是由该函数的实现方直接调用&#xff0c;而是在…

MySQL数据库的安装与实现

MySQL在win系统中的安装 第1步&#xff1a;下载安装&#xff08;在windows系统中安装&#xff09; http://downloads.mysql.com/archives/community/ 我选择安装的是5.7.31&#xff0c;一般MySQL主要分为两个版本&#xff0c;一个是5.7系列&#xff0c;一个是5.8系列&#xf…

CefSharp中ChromiumWebBrowser打开新页面时使用自己定义的窗体

CefSharp的Browser怎么说也是嵌入了Chromium的浏览器&#xff0c;所以碰到<a >标签“_blank”这样的时候&#xff0c;都是弹出新窗体打开新页面。但是怎奈我使用了DevExpress控件中的TabForm这个东西来作为主窗体&#xff0c;所以我不希望弹出新的窗体来&#xff0c;那么…

多线程并发检测触发器触发算法优化,附详细代码 - 定时执行专家

目录 ◆ V6.5版之前的并行检测方案 ◆ V6.5版之前的并行检测方案存在的问题 ◆ V6.5版本的并行检测方案 ◆ 定时执行专家 - 简介 ◆ 定时执行专家 - 最新版下载 一些用户说任务数量可能达到200个&#xff0c;让我比较惊讶&#xff0c;这个软件的设计之初并没有考虑这么多的…