掘金 后端 ( ) • 2024-05-16 13:46

前言

今天我们来用传统编程来爬虫,拿到豆瓣电影的电影列表。本文将介绍如何使用 Node.js 构建一个简单的网络爬虫,以获取豆瓣电影 Top250 的信息为例,通过分析网页结构、发送 HTTP 请求并解析 HTML 内容,最终将所需信息保存为 JSON 文件。

爬虫

爬虫,正式名称为网络爬虫(web crawler)或网络蜘蛛(web spider),是一种程序或脚本,设计用来自动地浏览互联网,并从中收集信息。它们通常被用来收集特定网站的数据,以供分析、索引或其他目的使用。网络爬虫通过HTTP请求获取网页内容,然后解析该内容以提取所需的信息,例如文本、链接、图像等。

简单来说,爬虫的工作流程通常包括以下步骤:

  1. 确定入口URL:确定几个初始的网页地址作为爬取的起点。
  2. 发送HTTP请求:爬虫向目标网站发送HTTP请求,请求页面的内容。
  3. 获取网页内容:目标网站收到请求后,返回相应的HTML页面。
  4. 解析网页内容:爬虫使用解析库(如BeautifulSoup、Scrapy、Cheerio等)对网页内容进行解析,提取出需要的数据。
  5. 数据处理:爬虫对提取的数据进行处理、清洗、存储或其他操作。
  6. 循环执行:重复以上步骤,直到满足预定的停止条件,比如抓取到足够多的数据,或者达到了预设的深度、广度限制。

网络爬虫在搜索引擎、数据挖掘、监控、信息聚合等领域都有广泛的应用。然而,值得注意的是,使用网络爬虫时需要遵守网站的robots.txt协议和相关法律法规,以确保爬取的行为合法合规。

准备流程

步骤1: 安装好Vscode(Download Visual Studio Code - Mac, Linux, Windows)和node(下载 | Node.js 中文网 (nodejs.cn),创建文件夹,鼠标右键在集成终端中打开,进入终端。

在Vscode中创建文件夹movie-crawl,如下图所示:

image.png

在文件夹movie-crawl上鼠标右键在集成终端中打开,进入终端,如下图所示: image.png

步骤2: 在终端输入npm init -y,可以初始化为后端项目,得到package.json项目描述文件。

输入npm init -y image.png package.json项目描述文件

image.png image.png

步骤3: 创建入口文件main.js,安排编程的流程,就可以开始写代码啦

Node.js爬虫

爬虫思想:他有我拿,首先要发送一个HTTP请求https://movie.douban.com/top250,得到html字符串。然后解析html字符串,拿到电影列表。最后将所有的电影对象组成数组,以json数组的方式返回。

代码实现

  1. 模块引入:首先引入了需要使用的模块,包括request-promise用于发送HTTP请求,cheerio用于解析HTML,fs用于文件操作,以及util提供的一些工具函数。
// 引入所需的模块
let request = require('request-promise') // 使用request-promise模块进行HTTP请求,需要先安装
let cheerio = require('cheerio') // 使用cheerio模块进行HTML解析,需要先安装
let fs = require('fs') // 使用fs模块进行文件操作
const util = require('util') // 使用util模块提供的工具函数

在终端输入npm i request-promise安装request-promise模块,npm i cheerio安装cheerio模块,npm i可以安装第三方包,安装其他模块只要在npm i后面加上就可以啦

image.png

image.png

这样就表示安装成功啦

image.png

  1. 电影信息数组:定义了一个空数组movies,用于存储电影信息。
// 用于存储电影信息的数组
let movies = []
  1. 基础链接:定义了豆瓣电影Top250的基础链接basicUrl
// 豆瓣电影Top250的基础链接
const basicUrl = 'https://movie.douban.com/top250'
  1. 一次执行函数once函数用于确保某个函数只执行一次。
// 用于确保某个函数只执行一次的函数
let once = function (cb) {
    let active = false
    if (!active) {
        cb()
        active = true
    }
}
  1. 输出函数log函数用于确保某段信息只输出一次。
// 输出函数,确保某段信息只输出一次
function log(item) {
    once(() => {
        console.log(item)
    })
}
  1. 解析电影信息函数getMovieInfo函数用于解析单个电影节点的信息。
// 解析电影信息的函数
function getMovieInfo(node) {
    let $ = cheerio.load(node) // 使用cheerio加载HTML节点
    let titles = $('.info .hd span') // 获取电影标题元素
    titles = ([]).map.call(titles, t => { // 使用map方法将标题元素转换为文本数组
        return $(t).text()
    })
    let bd = $('.info .bd') // 获取电影信息元素
    let info = bd.find('p').text() // 获取电影简介文本
    let score = bd.find('.star .rating_num').text() // 获取电影评分文本
    return { titles, info, score } // 返回电影信息对象
}
  1. 获取某一页的电影信息函数getPage函数用于获取某一页的电影信息。
// 获取某一页的电影信息
async function getPage(url, num) {
    let html = await request({ // 使用request-promise发送HTTP请求获取页面HTML
        url
    })
    console.log('连接成功!', `正在爬取第${num+1}页数据`)
    let $ = cheerio.load(html) // 使用cheerio加载HTML页面
    let movieNodes = $('#content .article .grid_view').find('.item') // 获取电影节点
    let movieList = ([]).map.call(movieNodes, node => { // 遍历电影节点列表并解析电影信息
        return getMovieInfo(node)
    })
    return movieList // 返回解析后的电影信息列表
}
  1. 主函数main函数是程序的主要逻辑,用于控制爬取流程。它循环爬取每一页的电影信息,并将结果写入JSON文件。
// 主函数,用于控制爬取流程
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)) // 获取当前页的电影信息并加入到列表中
    }
    console.log(list.length) // 输出爬取的电影数量
    // 将爬取的电影信息写入JSON文件
    fs.writeFile('./output.json', JSON.stringify(list), 'utf-8', () => { // 将电影信息列表写入JSON文件
        console.log('生成json文件成功!')
    })
}
  1. 执行主函数:在最后调用main函数来执行整个爬取过程。
main()

在终端输入node .\main.js

image.png

结果

爬取数据成功

image.png

最后生成output.json

image.png

总结

在本文中,我们通过一步步的准备流程,以及代码实现,成功构建了一个基于 Node.js 的简单网络爬虫,用于获取豆瓣电影 Top250 的信息。通过发送 HTTP 请求,解析 HTML 内容,我们获取了电影的标题、简介和评分等信息,并将其存储为 JSON 文件。这个实例展示了网络爬虫的基本工作原理,同时也带来了对 Node.js、request-promise、cheerio 等模块的应用实践。