在当今数字化的时代,数据的获取和管理变得越来越重要。本文将介绍如何使用 Node.js 实现从学院官网获取图片和新闻标题,并将其存储到 MySQL 数据库中。(如果你不想使用MySQL的话,后文有关于单独不储存到MYSQL数据库的详细说明)
一、背景与目标
我们的目标是从学院官网中提取所有的图片和特定板块的新闻标题,然后将这些数据保存到 MySQL 数据库中,以便后续的分析和使用。通过这个过程,我们可以更好地了解学院的动态信息,同时也展示了 Node.js 在网络数据爬取和数据库操作方面的强大能力。
页面如下 准备爬取该新闻的标题以及内容(包括图片)
我的学校的新闻站点和图片
检查学校官网查看源代码,发现其ID选择器名称,这为后面的读取提供了极大便利。
二、技术栈
- Node.js:使用 Node.js 的
https
模块来发送 HTTP 请求,获取学院官网的页面内容。 - Cheerio:一个类似于 jQuery 的库,用于在服务器端解析 HTML 页面,方便提取所需的数据。
- MySQL:用于存储爬取到的新闻标题,通过
mysql
模块进行数据库连接和操作。
三、代码实现过程
** 首先,我们配置了项目所需的模块,包括https、cheerio、fs(文件系统模块)、path和mysql。我们还设置了学院官网的 URL 和一个用于存储下载图片的本地目录。
检查并创建download目录,如果该目录不存在。这个目录将用于存储从学院官网下载的图片。
配置 MySQL 连接,指定数据库的主机、用户名、密码和数据库名称。成功连接到数据库后,会在控制台打印相应的消息。
使用https.get方法发送 HTTP 请求到学院官网。在请求的响应中,我们收集页面的 HTML 内容。
使用 Cheerio 加载 HTML 内容,以便进行数据提取。**
** **请注意:
** **(1)在vscode中,,你需要引入cheerio库函数,该函数是Cheerio 就像是服务器端的 jQuery。它可以在 Node.js 环境中解析 HTML 文档,让你能够以类似于使用 jQuery 的方式来操作和提取 HTML 中的元素和数据。但是该函数支持的Node.js版本挺高,笔者在完成作业时发现自身的版本并不适合,所以需要下载高版本的Node.js(最好是最新的,以防止后期需要下载插件的时候不匹配)。
** (2)如果直接运行代码会发生错误,需要在vscode下载的插件的时候使用命令:npm install cheerio。或者在运行的中途报错如果缺少什么模块,公式同上:npm+install+模块。**
实现思路:
(1)提取所有图片地址:通过遍历页面中的标签,获取每个图片的src属性。如果src属性存在,将其转换为绝对地址,并添加到imgUrls数组中。
(2)下载图片:对于每个图片地址,使用https.get方法进行下载,并将图片保存到本地download目录中。下载过程中会在控制台打印相应的消息,以便了解下载进度。
(3)获取校园快讯标题和媒体白云标题:分别遍历特定 ID 的标签,提取新闻标题。使用.trim()方法去除潜在的空格,确保标题的整洁。然后,将标题插入到 MySQL 数据库中的相应表中。
** 代码如下:**
js:
const https = require('https');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');
const mysql = require('mysql');
// 要获取的网页 URL
const baseUrl = 'https://www.baiyunu.edu.cn/';
const basePath = path.join(__dirname, 'download');
// 检查并创建 download 目录如果不存在
if (!fs.existsSync(basePath)) {
fs.mkdirSync(basePath, { recursive: true });
}
// 配置 MySQL 连接
const connection = mysql.createConnection({
host: '127.0.0.1',//如果是本机,那同上
user: 'root',
password: 'xxxxxx',//根据自己的情况来
database: 'xiaoyuantiqu'
});
connection.connect((err) => {
if (err) {
console.error('数据库连接错误:', err);
} else {
console.log('成功连接到 MySQL 数据库。');
}
});
https.get(baseUrl, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
const $ = cheerio.load(data);
// 提取所有图片地址
const imgUrls = [];
$('img').each((index, element) => {
let imgUrl = $(element).attr('src');
// 处理相对地址
if (imgUrl) {
imgUrl = new URL(imgUrl, baseUrl).href;
imgUrls.push(imgUrl);
}
});
// 打印所有图片地址并下载图片
imgUrls.forEach((imgUrl, index) => {
console.log(imgUrl);
downloadImg(imgUrl, index);
});
// 获取校园快讯标题并逐一插入数据库
$('#message a').each((index, element) => {
let title = $(element).text().trim(); // 使用.trim()去除潜在的空格
insertNews('campus_news', title); // 插入校园新闻
});
// 获取媒体白云标题并逐一插入数据库
$('#media a').each((index, element) => {
let title = $(element).text().trim();
insertNews('media_news', title); // 插入媒体新闻
});
});
}).on('error', (err) => {
console.error(`请求错误: ${err.message}`);
});
function downloadImg(url, filename) {
let ext = url.split('.').pop();
filename += '.' + ext;
console.log(`开始下载图片 ${filename}...`);
https.get(url, (res) => {
const file = fs.createWriteStream(path.join(basePath, filename));
res.pipe(file);
file.on('finish', () => {
console.log(`图片 ${filename} 下载完成.`);
});
}).on('error', (err) => {
console.error(`图片 ${filename} 下载失败: ${err.message}`);
});
}
function insertNews(tableName, title) {
connection.query(`INSERT INTO ${tableName} (title) VALUES (?)`, [title], (err) => {
if (err) {
console.error(`插入${tableName}标题错误:`, err);
} else {
console.log(`${tableName}标题已插入到数据库。`);
}
});
}
mysql:
CREATE DATABASE xiaoyuantiqu;
USE xiaoyuantiqu
CREATE TABLE campus_news (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(1000) NOT NULL
);
CREATE TABLE media_news (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(1000) NOT NULL
);
//SELECT USER,HOST FROM mysql.`user`;
//TRUNCATE TABLE campus_news;
//TRUNCATE TABLE media_news;
运行结果:
方法二(不连接Mysql):
提前配置好Node.js环境,提前在路径上创建文件夹download(方便读取图片),记事本(读取所需标题并保存)。
代码如下:
const https = require('https');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');
// 要获取的网页 URL
const baseUrl = 'https://www.baiyunu.edu.cn/';
const basePath = path.join(__dirname, 'download');
// 检查并创建 download 目录如果不存在
if (!fs.existsSync(basePath)) {
fs.mkdirSync(basePath, { recursive: true });
}
https.get(baseUrl, (res) => {
let data = '';
// 接收数据
res.on('data', (chunk) => {
data += chunk;
});
// 请求结束后处理数据
res.on('end', () => {
const $ = cheerio.load(data);
// 提取所有图片地址
const imgUrls = [];
$('img').each((index, element) => {
let imgUrl = $(element).attr('src');
// 处理相对地址
if (imgUrl) {
imgUrl = new URL(imgUrl, baseUrl).href;
imgUrls.push(imgUrl);
}
});
// 打印所有图片地址并下载图片
imgUrls.forEach((imgUrl, index) => {
console.log(imgUrl);
downloadImg(imgUrl, index);
});
// 获取校园快讯标题并写入记事本
const newsTitles1 = $('#message').map((index, element) => $(element).text()).get();
fs.writeFile('校园快讯.txt', newsTitles1.join('\n'), (err) => {
if (err) {
console.error('写入文件错误:', err);
} else {
console.log('校园快讯标题已写入 校园快讯.txt 文件。');
}
});
// 获取媒体白云标题并写入记事本
const newsTitles2 = $('#media').map((index, element) => $(element).text()).get();
fs.writeFile('媒体白云.txt', newsTitles2.join('\n'), (err) => {
if (err) {
console.error('写入文件错误:', err);
} else {
console.log('媒体白云标题已写入 媒体白云.txt 文件。');
}
});
});
}).on('error', (err) => {
console.error(`请求错误: ${err.message}`);
});
function downloadImg(url, filename) {
let ext = url.split('.').pop();
filename += '.' + ext;
console.log(`开始下载图片 ${filename}...`);
https.get(url, (res) => {
const file = fs.createWriteStream(path.join(basePath, filename));
res.pipe(file);
file.on('finish', () => {
console.log(`图片 ${filename} 下载完成.`);
});
}).on('error', (err) => {
console.error(`图片 ${filename} 下载失败: ${err.message}`);
});
}
如果不读取图片只是单纯读取标题
const axios = require('axios');
const fs = require('fs');
const url = "https://www.baiyunu.edu.cn/";
axios.get(url)
.then(response => {
const html = response.data;
const cheerio = require('cheerio');
const $ = cheerio.load(html);
const titles = $('#message');
let content = '';
titles.each((index, element) => {
content += $(element).text() + '\n';
});
// 写入到记事本文件
fs.writeFileSync('校园快讯.txt', content);
})
.catch(error => {
console.error('Error fetching data:', error);
});
运行结果:
四、总结
通过这段 Node.js 代码,我们成功地实现了从学院官网爬取图片和新闻标题,并将其存储到 MySQL 数据库中。这个过程展示了 Node.js 在网络数据爬取和数据库操作方面的灵活性和高效性。我们可以根据实际需求进一步扩展这个代码,比如添加错误处理机制、优化数据库插入操作等。希望这个示例能够为大家在 Node.js 数据爬取和数据库操作方面提供一些参考和启示。祝同学们学业进步,事事顺心!
版权归原作者 热爱算法的小羊 所有, 如有侵权,请联系我们删除。