likes
comments
collection
share

用Node.js做一个爬虫,泰裤啦!

作者站长头像
站长
· 阅读数 54

前言

在Node.js的广阔天地里,构建一个前端驱动的爬虫项目,无疑是一场既刺激又充满挑战的探险。想象一下,你将驾驭着代码的帆船,穿梭于互联网的浩瀚数据海洋,精准捕获那些散落在各个角落的宝贵信息。不同于传统后端主导的爬虫,利用Node.js前端技术栈不仅赋予了我们更灵活的网页交互能力,还让我们能够以前端开发者熟悉的视角,去理解和操控爬取过程中的每一个细节。

这次旅程,我们将揭开神秘的“泰裤啦”序幕,这不仅仅是一个简单的数据抓取任务,更是一次技术与策略的综合演练。从初始化环境、设计爬虫策略、模拟用户行为到高效解析数据,每一步都考验着你的创意与技巧。更重要的是,我们会注重遵守网站的协议,尊重数据来源,保证采集活动的合法性与道德性。

准备好了吗?让我们一起启航,用Node.js的强大力量,探索数据的无限可能,打造属于自己的智能信息搜集利器。在这条既实用又富有乐趣的编程之路上,每一次成功抓取,都是对你技术实力的最佳证明。泰裤啦,不仅仅是目标,更是一声充满激情的行动号令,引领我们在数据的浪潮中乘风破浪,发现新知。

1.基础知识

爬虫 Crawl

他有我拿 :浏览器只是上网的代理proxy, 先发送一个HTTP请求 url, GET movie.douban.com/chart 响应 html 字符串 , 解析html字符串,如果可以像css选择器一样,拿到了电影列表 最后将所有的电影对象组成数组,以json数组的方式返回

node 爬虫 后端功能

  1. npm init -y 初始化: 这个命令是用来创建一个新的 package.json 文件,它是Node.js项目的配置文件。package.json 文件包含了关于项目的重要元数据,如项目名称、版本、描述、作者、许可证、依赖关系等。当你执行 npm init -y 时,npm会跳过一系列交互式提问环节,直接采用默认值生成文件,这使得初始化过程非常迅速。
  2. package.json: 这个文件对于Node.js项目至关重要,它不仅存储了项目的基本信息,还列出了所有项目依赖(包括生产环境和开发环境依赖),以及定义了脚本命令(scripts)。在后端项目中,这些依赖可能包括数据库驱动、框架(如Express、Koa、Hapi等)、中间件、安全库等。
  3. npm i 或 npm install: npm i 是 npm install 的简写形式,用于安装项目依赖。当你在 package.json 文件中指定了依赖后,通过运行这个命令,npm会自动下载并安装这些依赖到项目的 node_modules 目录下。对于后端项目,这一步通常会在添加新的库或框架后执行,以确保项目环境正确设置。
  4. require: 在Node.js中,require 是一个函数,用于加载和使用模块。在后端项目中,你可能会用它来引入自己编写的模块、第三方库或Node.js内置模块。例如,const express = require('express'); 用来引入Express框架。
  5. main.js 或其他入口文件: 这是Node.js应用的启动点,通常被指定在 package.json 文件的 "main" 字段。在后端项目中,这个文件可能包含服务器的配置、路由设定、中间件应用、错误处理等核心逻辑。例如,一个简单的Express应用可能会在 main.js 或 app.js(或其他任何你指定的文件名)中写入 const app = express(); app.listen(3000); 来启动服务器。

2.执行过程

在此之前我们需要打开终端输入npm init -y 初始化为后端项目,然后安装需要的库,再进行操作。

代码

// 导入所需模块
let request = require('request-promise'); // 用于发送HTTP请求的库
let cheerio = require('cheerio'); // 用于解析HTML的库
let fs = require('fs'); // 文件系统模块,用于文件操作
const util = require('util'); // Node.js内置工具模块

// 初始化电影列表和基础URL
let movies = [];
let basicUrl = 'https://movie.douban.com/top250';

// 防止并发控制的函数,确保某段代码只被执行一次
let once = function (cb) {
    let active = false;
    return function() {
        if (!active) {
            active = true;
            cb();
        }
    };
};

// 日志打印函数,利用once确保日志不重复打印
function log(item) {
    once(() => {
        console.log(item);
    });
}

// 提取单个电影信息的函数
function getMovieInfo(node) {
    let $ = cheerio.load(node); // 使用cheerio加载HTML节点
    let titles = $('.info .hd span'); // 获取标题元素
    titles = Array.from(titles).map(t => $(t).text()); // 将标题文本内容提取到数组
    let bd = $('.info .bd'); // 获取电影信息块
    let info = bd.find('p').text(); // 提取简介文本
    let score = bd.find('.star .rating_num').text(); // 提取评分
    return { titles, info, score }; // 返回电影信息对象
}

// 获取单页电影列表的异步函数
async function getPage(url, num) {
    let html = await request({ url }); // 发起请求获取HTML
    console.log('连接成功!', `正在爬取第${num + 1}页数据`); // 打印日志
    let $ = cheerio.load(html); // 解析HTML
    let movieNodes = $('#content .article .grid_view').find('.item'); // 获取电影项
    let movieList = Array.from(movieNodes).map(node => getMovieInfo(node)); // 提取各电影信息
    return movieList; // 返回当前页电影列表
}

// 主函数,执行爬虫逻辑
async function main() {
    let count = 25; // 需爬取的页数
    let list = []; // 存储所有电影信息的列表
    for (let i = 0; i < count; i++) {
        let url = `${basicUrl}?start=${25 * i}`; // 构造URL
        list.push(...await getPage(url, i)); // 爬取每页数据并添加到list
    }
    console.log(list.length); // 打印总数
    fs.writeFile('./output.json', JSON.stringify(list), 'utf-8', () => { // 写入文件
        console.log('生成json文件成功!');
    });
}
// 启动主函数
main();

执行逻辑

这段代码使用Node.js编写,目的是从豆瓣电影Top250的网页中抓取电影信息,并将抓取到的数据保存至一个JSON文件中。

  1. 引入依赖:

    • 首先通过require导入了四个模块:request-promise用于发送HTTP请求,cheerio用于解析HTML文档,fs用于文件系统操作(如读写文件),以及util模块虽然被引用但未直接使用。
  2. 定义变量:

    • 定义了movies数组用于存储电影信息,basicUrl为豆瓣电影Top250的基础URL,以及一些辅助函数和变量。
  3. 防并发控制:

    • 定义了一个once函数,用于防止日志输出的并发问题,确保同一时间只打印一条日志。
  4. 日志功能:

    • log函数内部使用once确保日志信息不会因为并发请求而重复打印。
  5. 获取电影信息:

    • getMovieInfo函数接收一个HTML节点,使用cheerio解析节点,从中提取电影标题、简介和评分等信息,并以对象形式返回。
  6. 抓取页面数据:

    • getPage函数接收一个URL和页码num作为参数,向指定URL发送HTTP请求,获取HTML内容。使用cheerio解析HTML,找到所有电影项目节点,对每个节点调用getMovieInfo获取详细信息,并收集所有电影信息为一个数组返回。
  7. 主逻辑:

    • main函数是程序的主要执行逻辑,循环请求前25页(每页25部电影)的数据,每次请求的URL通过页码计算得出,将每页抓取到的电影信息累加到list数组中。完成所有请求后,将list转换为JSON字符串并写入output.json文件。
  8. 程序启动:

    • 最后,调用main()函数开始整个抓取流程。
转载自:https://juejin.cn/post/7369534132081737766
评论
请登录