node 写爬虫,原来这么简单

作者:CarsonXu

原文地址:https://juejin.im/post/5eca37f951882543345e81df

前言

今天给大家带来的是node简单爬虫,对于前端小白也是非常好理解且会非常有成就感的小技能

爬虫的思路可以总结为:请求 url - > html(信息) -> 解析html

这篇文章呢,就带大家爬取豆瓣TOP250电影的信息。

  

工具

爬虫必备工具:cheeriocheerio 简单介绍:cheerio 是 jquery 核心功能的一个快速灵活而又简洁的实现,主要是为了用在服务器端需要对 DOM 进行操作的地方。大家可以简单的理解为用来解析 html 非常方便的工具。使用之前只需要在终端安装即可 npm install cheerio

node爬虫步骤解析

一、选取网页url,使用http协议get到网页数据

豆瓣TOP250链接地址:https://movie.douban.com/top250

首先我们请求http协议,通过http来拿到网页的所有数据

const https = require('https');
https.get('https://movie.douban.com/top250',function(res){
    // 分段返回的 自己拼接
    let html = '';
    // 有数据产生的时候 拼接
    res.on('data',function(chunk){
        html += chunk;
    })
    // 拼接完成
    res.on('end',function(){
        console.log(html);
    })
})

上面代码呢,大家一定要注意我们请求数据时,拿到的数据是分段拿到的,我们需要通过自己把数据拼接起来

res.on('data',function(chunk){
        html += chunk;
    })

拼接完成时 我们可以输出一下,看一下我们是否拿到了完整数据

res.on('end',function(){
        console.log(html);
    })

二、使用cheerio工具解析需要的内容

const cheerio = require('cheerio');
res.on('end',function(){
        console.log(html);
        const $ = cheerio.load(html);
        let allFilms = [];
        $('li .item').each(function(){
            // this 循环时 指向当前这个电影
            // 当前这个电影下面的title
            // 相当于this.querySelector 
            const title = $('.title', this).text();
            const star = $('.rating_num',this).text();
            const pic = $('.pic img',this).attr('src');
            // console.log(title,star,pic);
            // 存 数据库
            // 没有数据库存成一个json文件 fs
            allFilms.push({
                title,star,pic
            })
        })

可以通过检查网页源代码查看需要的内容在哪个标签下面,然后通过$符号来拿到需要的内容,这里我就拿了电影的名字、评分、电影图片

  

  

  

到了这时候,你会发现,node 爬虫实现是非常简单的,我们只需要认真分析一下我们拿到的 html 数据,将需要的内容拿出来保存在本地就基本完成了

保存数据

下面就是保存数据了,我将数据保存在 films.json 文件中 将数据保存到文件中,我们引入一个fs模块,将数据写入文件中去

const fs = require('fs');
fs.writeFile('./films.json', JSON.stringify(allFilms),function(err){
            if(!err){
                console.log('文件写入完毕');
            }
        })

文件写入代码需要写在 res.on('end') 里面,数据读完->写入 写入完成,可以查看一下films.json,里面是有爬取的数据的。

下载图片

我们爬取的图片数据是图片地址,如果我们要将图片保存到本地呢?这时候只需要跟前面请求网页数据一样,把图片地址url请求回来,每一张图片写入到本地即可

function downloadImage(allFilms) { for(let i=0; i<allFilms.length; i++){ const picUrl = allFilms[i].pic; // 请求 -> 拿到内容 // fs.writeFile('./xx.png','内容') https.get(picUrl,function(res){ res.setEncoding('binary'); let str = ''; res.on('data',function(chunk){ str += chunk; }) res.on('end',function(){ fs.writeFile(./images/${i}.png,str,'binary',function(err){ if(!err){ console.log(第${i}张图片下载成功); } }) }) }) } } 复制代码 下载图片的步骤跟爬取网页数据的步骤是一模一样的,我们将图片的格式保存为.png写好了下载图片的函数,我们在 res.on('end') 里面调用一下函数就大功告成了

源码

// 请求 url - > html(信息)  -> 解析html
const https = require('https');
const cheerio = require('cheerio');
const fs = require('fs');
// 请求 top250
// 浏览器输入一个 url, get
https.get('https://movie.douban.com/top250',function(res){
    // console.log(res);
    // 分段返回的 自己拼接
    let html = '';
    // 有数据产生的时候 拼接
    res.on('data',function(chunk){
        html += chunk;
    })
    // 拼接完成
    res.on('end',function(){
        console.log(html);
        const $ = cheerio.load(html);
        let allFilms = [];
        $('li .item').each(function(){
            // this 循环时 指向当前这个电影
            // 当前这个电影下面的title
            // 相当于this.querySelector 
            const title = $('.title', this).text();
            const star = $('.rating_num',this).text();
            const pic = $('.pic img',this).attr('src');
            // console.log(title,star,pic);
            // 存 数据库
            // 没有数据库存成一个json文件 fs
            allFilms.push({
                title,star,pic
            })
        })
        // 把数组写入json里面
        fs.writeFile('./films.json', JSON.stringify(allFilms),function(err){
            if(!err){
                console.log('文件写入完毕');
            }
        })
        // 图片下载一下
        downloadImage(allFilms);
    })
})

function downloadImage(allFilms) {
    for(let i=0; i<allFilms.length; i++){
        const picUrl = allFilms[i].pic;
        // 请求 -> 拿到内容
        // fs.writeFile('./xx.png','内容')
        https.get(picUrl,function(res){
            res.setEncoding('binary');
            let str = '';
            res.on('data',function(chunk){
                str += chunk;
            })
            res.on('end',function(){
                fs.writeFile(`./images/${i}.png`,str,'binary',function(err){
                    if(!err){
                        console.log(`第${i}张图片下载成功`);
                    }
                })
            })
        })
    }
}

总结

爬虫不是只有 python 才行的,我们 node 也很方便简单,前端新手掌握一个小技能也是非常不错的,对自身的 node 学习有很大的帮助,本文的爬虫技巧只是入门,感兴趣小伙伴可以继续探究。

Node.js 爬虫添加定时功能通常通过使用各种时间管理库和 Node.js 的特性来实现。下面是一个简化的步骤说明: ### 使用计划任务 (cron jobs) 添加定时爬虫 对于 Linux 和 macOS 操作系统,你可以利用 cron 工具来设置定时任务。在 Windows 系统上,通常使用 Task Scheduler。 #### 步骤一:编爬虫脚本 首先,你需要有一个运行爬虫的 JavaScript 文件。例如,我们假设已经创建了一个名为 `scrape.js` 的文件,该文件包含了一些基本的爬虫逻辑。 ```javascript // scrape.js const axios = require('axios'); async function fetchData(url) { try { const response = await axios.get(url); console.log(response.data); } catch (error) { console.error(`Error fetching data from ${url}:`, error); } } fetchData("https://example.com"); ``` #### 步骤二:配置 crontab 或 Task Scheduler 接下来,在 Linux/macOS 上,打开 crontab 来编辑定时任务: - 打开终端并输入 `crontab -e` 进入文本编辑器。 然后在文件中添加一行命令来指定爬虫任务的定时执行。例如,为了每天凌晨两点执行爬虫,可以添加以下行: ```bash 0 2 * * * /usr/bin/node /path/to/scrape.js > /path/to/logfile.txt 2>&1 ``` 这条命令的意思是在每天凌晨两点执行 `/path/to/scrape.js` 脚本,并将输出结果和错误信息入到 `/path/to/logfile.txt` 中。 保存并关闭文件后,需要重启 crond 服务让新的定时任务生效: ```bash sudo service crond restart ``` 在 Windows 系统上,使用 Task Scheduler 设置定时任务更为直观,步骤包括选择新建任务、设定触发条件、指向执行的 .js 文件等操作。详细步骤取决于系统的版本和具体的用户权限情况。 #### 关联的其他问题: 1. **如何调试 Node.js 爬虫**? 使用日志记录和断点定位错误是非常重要的调试手段,如在 `scrape.js` 中添加 `console.log()` 或者使用像 Mocha 测试框架配合 Chai 断言来进行测试。 2. **如何优化 Node.js 爬虫性能**? 通过限制并发请求数、使用缓存技术、优化网络通信等策略可以提高爬虫效率和稳定性。 3. **处理异步回调和 Promise 在 Node.js 爬虫中的应用**? 异步编程模型是 Node.js 的核心,理解并善用回调函数、Promise 和 async/await 可以使爬虫代码更清晰、易于维护。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值