【初识node】node模块,npm库换源,node多页面应用爬虫

今天,我们来用node实现一个多页面应用的爬虫操作,在进行爬虫操作之前,我们需要了解一些基本知识

什么是node?

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。它使用了事件驱动、非阻塞 I/O 模型,使得 JavaScript 代码可以在服务器端高效运行。

我们要知道node不是一门编程语言!

Node.js 的主要特点包括:

  1. 事件驱动:Node.js 使用事件驱动的编程模型,通过回调函数来处理异步操作。
  2. 非阻塞 I/O:Node.js 中的 I/O 操作(如文件读写、网络请求等)是非阻塞的,不会阻塞后续代码的执行。
  3. 单线程:Node.js 是单线程的,但通过事件循环和回调机制来实现并发处理。
  4. 模块系统:Node.js 拥有强大的模块系统,可以方便地导入和导出模块。
  5. 社区活跃:Node.js 有一个活跃的社区,提供了丰富的第三方库和工具。

Node.js 常用于构建高性能的 Web 服务器、后端应用程序、实时数据处理等。它也适用于 IOT(物联网)、移动应用开发和命令行工具等领域。

我们先来了解一下node的一些基本的语法!

模块:例如:console

在 Node.js 中,模块是一种组织代码的方式。模块可以将相关的功能和代码封装在一起,使代码更具有可维护性和可重用性。

每个模块都可以导出一些函数、对象或变量,其他模块可以通过导入这个模块来使用其中导出的内容。

我们经常使用的一个指令console.log()

consolenode里面的一个模块,console是一个对象,后面可以接很多种方法!

Node.js 的 console 模块提供了在控制台上打印消息、调试信息和错误的方法。它是一个内置模块,用于输出日志、数据和其他信息,以便在开发和运行过程中进行调试和监控。

以下是 console 模块常用的方法:

  1. console.log(): 用于打印普通消息或数据到控制台。
  2. console.error(): 用于打印错误消息到控制台。
  3. console.warn(): 用于打印警告消息到控制台。
  4. console.info(): 用于打印信息性消息到控制台。
  5. console.debug(): 用于打印调试消息到控制台。

具体可以在官方文档:console 控制台 | Node.js v20 文档 (nodejs.cn)查看!

我们可以通过使用 console 模块,可以在 Node.js 应用程序中方便地输出各种类型的消息,帮助调试代码、监控程序的运行状态和了解程序的行为等一系列操作。

我们在js有一些方法!其实在node中也是可以执行出来的!例如:

js 复制代码
console.log(Date);
console.log(Math);

输出:
[Function: Date]
Object [Math] {}

当然在js中有一个定时器,这个也是可以在node中使用的!

js 复制代码
setTimeout(()=>{
    console.log('setTimeout');
},2000)
输出:
setTimeout

还有一个setIntervalsetImmediate

js 复制代码
console.log(setInterval);
console.log(setImmediate);

输出:
[Function: setInterval]
[Function: setImmediate] {
  [Symbol(nodejs.util.promisify.custom)]: [Getter]
}

这些js中的定时器在node当中都是可以识别的!当然在浏览器中还有一个定时器 requestAnimationFrame,这个是浏览器环境下的一个函数,这个函数在node中是无法识别的!

requestAnimationFrame是浏览器环境下的一个类似定时器的函数,时间是固定的,是根据电脑屏幕的刷新率来设定的,时间是不需要我们去手动设置的。

要想实现后端的功能,与我们的操作系统打交道是必不可少的!我们再介绍两个语句

js 复制代码
console.log(__dirname)//读取到当前文件夹的绝对路径,当前文件所处的文件夹的绝对路径;
console.log(__filename);//读取到某个文件所在的绝对路径

输出:
C:\Desktop\codespace\node\spider\base
C:\Users\www16\Desktop\codespace\node\spider\base\1.js

这种语句是js中没有的内容,还有一个语句可以查看当前的进程!

js 复制代码
console.log(process);

大家可以新建一个文件夹尝试一下!

argv指令+剪刀石头布Demo

node当中有一个argv指令,可以接收人为输入的指令!例如:

js 复制代码
console.log(process.argv);

我们在终端这样输入:node 1.js hello

输出:
[
  'C:\\Program Files\\nodejs\\node.exe',
  'C:\\Users\\www16\\Desktop\\codespace\\node\\spider\\base\\1.js',
  'hello'
]

我们可以通过这样的语句获取到我们输入的最后一条指令!

js 复制代码
process.argv[process.argv.length - 1]

有了这样一个思路,我们就可以做一个简单的剪刀石头布demo了!

js 复制代码
let player = process.argv[process.argv.length - 1]
//用电脑随机生成一个
let arr = ['rock','scissors','paper']
let index = Math.floor(Math.random()*arr.length)
let computer = arr[index]
//比较规则
if(computer === player)
{
    console.log('平局');
}else if(
    (computer==='rock'&& player==='paper')||
    (computer==='scissors'&& player==='rock')||
    (computer==='paper'&& player==='scissors')
    ){
        console.log('你赢了');
}else{
    console.log('你输了');
}

我们就可以试试这样一个石头剪刀布游戏是否成功!

node 复制代码
PS C:\Users\www16\Desktop\codespace\node\spider\base> node 2.js rock
你输了
PS C:\Users\www16\Desktop\codespace\node\spider\base> node 2.js rock
平局

npm库

node还有一个npm库!也就是装轮子!我们可以通过npm安装很多大佬封装好的功能!

我们首先要做的就是对项目进行初始化!在终端运行下述指令!

node 复制代码
npm init

初始化的过程中我们需要做一个选择,这个大家按需选择就可以!

我们可以创建一个index.js入口文件! 入口文件是应用程序开始执行的文件。

我们有一个仓库网站:npm | Home (npmjs.com)

在这个网站,我们可以找到我们需要的功能!找到安装的指令,我们只需要运行一下相应的指令,我们就可以将相应的功能包安装到我们的项目当中!

大家可以会遇到下载速度慢等问题!我们就需要对npm库进行换源!

我们有很多国内的厂商会把npm库的数据拷贝下来,方面国内用户的使用,并且实时更新,所以我们就可以通过一些指令将下载源换到我们国内厂商的地址,这样下载速度也会提高!

我们可以使用这个指令查看我们当前的下载源:(在终端运行)

node 复制代码
npm config get registry

我们如何换源呢?例如:

node 复制代码
npm config set registry 地址

这是国内大佬总结的一些npm源镜像!

npm 官方原始镜像网址是:registry.npmjs.org/ 淘宝 NPM 镜像:旧:registry.npm.taobao.org 新:registry.npmmirror.com 阿里云 NPM 镜像:npm.aliyun.com 腾讯云 NPM 镜像:mirrors.cloud.tencent.com/npm/ 华为云 NPM 镜像:mirrors.huaweicloud.com/repository/... 网易 NPM 镜像:mirrors.163.com/npm/ 中科院大学开源镜像站:mirrors.ustc.edu.cn/ 清华大学开源镜像站:mirrors.tuna.tsinghua.edu.cn/

大家可以挑一个合适的进行使用!

我们装好npm库中的包之后,我们可以在node_modules文件中看到我们下载的源代码,这个文件就是存放各种依赖包的位置(第三方的包)。

下载好之后,我们就可以引入并且使用相应包的功能了!

接下来,我们今天来尝试一下使用node来写一个多页面应用爬虫!

node多页面应用爬虫

首先,我们可以拿一个豆瓣Top250网站作为我们的目标网址:movie.douban.com/top250

就比如,我们要把第一页的25个电影拿到!

首先我们新建一个文件夹spider,再用npm init初始化项目!

再新建一个index.js文件作为入口文件!

我们要用到一个node自带的一些模块:https超文本传输协议中的get方法!https 安全超文本传输协议 | Node.js v20 文档 (nodejs.cn)

所以我们再index.js文件中干第一个操作!我们可以看官方文档的语法!

js 复制代码
const https = require('https')

https.get('https://movie.douban.com/top250',(res)=>{

})

在官方文档中这样描述的

可以看到对于回调函数中的res有一个on方法!这个方法的功能是监听数据的读取

于是乎,我们的代码就可以写成这样了!

js 复制代码
const https = require('https')

https.get('https://movie.douban.com/top250',(res)=>{
	res.on('data',(chunk)=>{
		console.log(chunk)
	})
})

我们可以使用console.log(chunk);输出的是十六进制的数据。

我们要的不是这样的数据,我们可以使用toString方法或者chunk+''就可以拿到一个源代码的数据

console.log(chunk+'');

这样其实拿到的就是豆瓣页面上的源代码数据!因为数据过长,所以我们现在的代码是进行多次读取的,是一个缝合怪的结果!

js 复制代码
const https = require('https')

https.get('https://movie.douban.com/top250',(res)=>{
	let html = ''
	res.on('data',(chunk)=>{
		console.log(chunk +'')
		html += chunk
	})
})

所以,我们就可以用一个html变量去把数据拿着自动拼接拿到的数据!我们怎么判断数据拿完了呢?

res.on方法中可以监听一个end关键字,来判断数据是否获取完毕!

js 复制代码
res.on('end',()=>{
	//源代码获取完毕!
})

接下来,我们就是读取到源代码中的我们想要的数据!在以前js的语法中,我们用的是document获取页面的Dom结构,但是在node中不行!doucument是浏览器赋予的,node里面不能写!那我们在node中怎么操作html呢?

这里我们就需要使用npm库中的一个cheerio包了!cheerio - npm (npmjs.com)

这个包,就允许我们在node环境下操作html

所以我们接下来的步骤就是使用npm安装这个包!

npm 复制代码
npm i cheerio

接下来,我们这样使用cheerio,

js 复制代码
const cheerio = require('cheerio')
const https = require('https')

https.get('https://movie.douban.com/top250',(res)=>{
    let html = ''
    res.on('data',(chunk)=>{
        html += chunk
    })
    res.on('end',()=>{
        //源代码获取完毕!
        const $ = cheerio.load(html)
        // 定义一个数组 存储数据
        const result = []
        //我们观察源代码,可以知道我们要的数据是来自li .item中的 .info .title和.info .bd .retring_num和.pic img 根据cheerio官方文档的用法有一个each遍历方法,接下来我们这样写
        $('li .item').each(function(){
            // 拿到标题 找到.info容器下面的.title
            const title =  $('.info .title',this).text()
            // 拿到评分
            const star = $('.info .bd .rating_num',this).text()
            //拿到电影的图片,取.pic下面的img标签,我们读属性用attr
            const pic = $('.pic img',this).attr('src')
            //把数据放入到数组当中,数据放入对象当中存入数组,这是解构语法
            result.push(
                {
                    title,
                    star,
                    pic
                }
            )
        })
        //打印数据
        console.log(result);
    })
})

写到这里,我们就可以看到我们拿到的数据了!

接下来,我们就需要把数据写入到本地当中,在node当中有一个fs模块,里面有一个方法writeFile,我们可以用JSON.stringify(result)将数据转换为JSON格式,这个方法有三个参数

第一个参数是:写入位置

第二个参数是:JSON.stringify(result)

第三个参数是:一个回调函数,回调函数有两个参数(err,data),如果err有值就是写入失败,如果没有值就是写入成功!所以现在我们的代码写成这样

js 复制代码
const https = require('https')
const cheerio = require('cheerio')
const fs = require('fs')//node 里面自带的fs模块 与文件操作
https.get('https://movie.douban.com/top250',(res)=>{
    //因为数据过长,这个data会反复执行的
    let html = ''
    res.on('data',(chunk)=>{
        html += chunk
    })
    res.on('end',()=>{
        //源代码获取完毕
        const $ = cheerio.load(html)
        // 定义一个数组,存储数据
        const result = []
        $('li .item').each(function(){
            // 拿到标题
            const title =  $('.info .title',this).text()
            // 拿到评分
            const star = $('.info .bd .rating_num',this).text()
            //拿到电影的图片,取.pic下面的img标签,我们读属性用attr
            const pic = $('.pic img',this).attr('src')
            //把数据放入到数组当中,数据放入对象当中存入数组,这是解构语法
            result.push(
                {
                    title,
                    star,
                    pic
                }
            )
        })

        console.log(result);
        fs.writeFile('./list.json', JSON.stringify(result),(err,data)=>{
            if(err)
            {
                throw err
            }
            console.log('文件写入成功!');
        })
    })
})

运行之后,我们就会发现,在我们的目录中出现了一个新的文件list.json

这个文件内容默认是不换行的,我们可以右键格式化一下:

于是我们就拿到最后的数据了

最后

我们这个node爬虫,只适用于那些传统的多页面应用网址,如果使用的是vue等其他框架编写的网站是无法用我们这个爬虫取爬取数据的,不过大家也可以使用这个豆瓣网站进行尝试!

如果,你觉得这篇文章有帮助的话,可以帮博主点赞+评论+收藏,三连一波!感谢!

往后,我还会持续输出vue相关的文章,如vue路由原理,node相关的内置模块,koa的使用等等文章,感兴趣的小伙伴可以关注一波!

代码以上传至个人Github:一个修远君的库 (github.com)

相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang1 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui