const express = require("express")
const request = require("request")
const fs = require('fs')
// 后端 jQ
const cheerio = require("cheerio")
var app = express()
// 后端没有window
// 设置静态资源目录
app.use(express.static(__dirname+"/public"))
request({
url: 'https://sale.vmall.com/618new.html?cid=10618'
}, (err, res, data) => {
if (err) {
return console.log('错误信息:', err);
}
// console.log("data", data);
// 爬取得网页写入到本地htm文件中
// 方便我们查看 爬取得结果
fs.writeFile(__dirname + "/1.html", data, (err) => {
if (err) {
return console.log("爬取数据 写入文件失败", err);
}
console.log("写入成功");
})
// 爬虫 目的 为了分析爬取得数据
// 所以我们 现在开始抓取我们想要的数据
// 后端jQ解析 爬取的网页
var $ = cheerio.load(data)
// 因为所有的商品都在 li里面 我们没有必要挨个爬取 图片 标题 描述
// 通过找到所有的列表li 然后遍历li,得到里面的内容
var arr = []
$(".grid-list li").each(function () {
// 抓取 到我们想要的数据 首先现存起来
arr.push({
// 爬取商品的标题
title: $(this).find(".title").html(),
// 爬取商品图片
imgSrc: $(this).find("img").attr("src"),
// 爬取上面描述
desc: $(this).find(".desc").attr("title"),
// 爬取价格
price: $(this).find(".price-amount").html()
})
})
// 这样查看数据 也不方便 所以写到json里面
// 注意写到 arr 存储完毕 外面
fs.writeFile(__dirname + "/data.json", JSON.stringify(arr), (err) => {
if (err) {
return console.log(" 写入json文件失败", err);
}
console.log("写入json成功");
})
})
// 指定模板目录
// app.set("指定模板")
// views 是固定的 不能改的
app.set("views", __dirname + "/view")
// 指定渲染引擎
// app.set("view engine","引擎名字")
app.set("view engine", "ejs")
// 客户端请求
app.get("/", (req, res) => {
fs.readFile(__dirname + "/data.json", (err, data) => {
if (err) {
return console.log(" 读取数据失败", err);
}
console.log("读取数据成功");
// 把数据返回给前端 并渲染出来
// 模板名字不需要加后缀
// 用的时候需要转化一下 因为写入的时候 用了JSON压缩成了字符串了
res.render("index", { list: JSON.parse(data.toString()) })
})
})
app.listen(8769, () => {
console.log("8769 服务器启动");
})
以上是第一种方式,是数据转为JSON数据后,在渲染。
需要注意的地方:
// 设置静态资源目录 ,在html中可直接写引用文件名
app.use(express.static(__dirname+"/public"));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="index.css">
<style>
ul{
list-style: none;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
text-align: center;
}
</style>
</head>
<body>
<ul>
<% list.forEach(function(item){%>
<li>
<img src="<%= item.imgSrc %>" alt="">
<h2><%= item.title %> </h2>
<p><%= item.desc %></p>
<p><%= item.price %>元</p>
</li>
<% }) %>
</ul>
</body>
</html>
第二种方式:通过数据添加到数据组后,直接渲染到页面
const cheerio = require('cheerio')
const request = require('request')
const ejs = require("ejs")
const express = require("express")
var app = express()
request({
url: 'https://sale.vmall.com/618new-.html?cid=10618'
}, function (err, res, body) {
if (err) {
return console.log('错误信息:', err);
}
// 获取数据
var $ = cheerio.load(body)
//把获取的数据存储到arr里面
var arr = {
list: []
}
// 选择器 class . id #不要忘记
$(".grid-list li").each(function () {
arr.list.push({
// 爬取商品的标题
title: $(this).find(".title").html(),
// 爬取商品图片
imgSrc: $(this).find("img").attr("src"),
// 爬取上面描述
desc: $(this).find(".desc").attr("title"),
price: $(this).find(".price-amount").html()
})
// 客户端触发 模板请求
app.get("/", (req, res) => {
ejs.renderFile(__dirname + "/75.html", arr, function (err, data) {
if (err) {
return console.log("渲染出错", err);
}
res.end(data)
})
})
})
})
// 监听端口
app.listen(6789, () => {
console.log("6789服务启动");
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
padding: 0;
border: 0;
text-decoration: none;
list-style: none;
}
body{
background-color: darksalmon;
/* width: 100%; */
}
.headimg{
width: 100%;
}
#uls{
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
#uls>li{
width: 280px;
height: 300px;
background-color: white;
text-align: center;
margin: 20px 20px;
}
#uls>li>img{
width: 180px;
height: auto;
}
</style>
</head>
<body>
<img
class="headimg"
src="https://res6.vmallres.com/shopdc/pic/2021617/244f8dd4-bcf8-432a-b2e0-6706c1fb950e.png"
alt=""
/>
<ul id="uls">
<% for(var i=0;i<list.length;i++){ %>
<li>
<img src="<%= list[i].imgSrc %>" alt="">
<p><%= list[i].title %> </p>
<p><%= list[i].desc %> </p>
<div class="bot">
<span >¥</span>
<span><%= list[i].price %></span>
</div>
</li>
<% } %>
</ul>
</body>
</html>