UED Landing 页 - 定时抓取掘金文章
![](https://img.blogweb.cn/article/6319f2f1527f4b4eab547fbd01d9504f.webp)
## 需求介绍
## 设计思路
基于上述的需求分析后,进行以下设计:
2、将上述方法拿到的数据处理后存入 MongoDB 数据库,只保留需要的字段;
3、提供一个 RESTful 风格的接口,分页返回文章列表和标签列表,供专栏页面查询使用;
4、页面请求接口,查询标签、文章数据 ,渲染页面。
## 实现步骤
以下实现步骤比较详细,类似的需求也可以按以下步骤去实现。
### Docker 安装 MongoDB
1、下载镜像
```
docker pull mongo
```
2、创建挂载文件夹
```bash
mkdir -p /opt/dtstack/docker/mongo
cd /opt/dtstack/docker/mongo
```
3、启动容器
```bash
docker run -v /opt/dtstack/docker/mongo:/data/db --name mongodb -p 27019:27017 -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD='Admin123!@#' -d mongo --auth
```
**命令解释**
+ \-v 挂载本地文件夹,存储数据
+ \-name 给容器指定名称
+ \-p 表示端口映射,`-p 宿主机port:容器port`,这里不使用相同端口是为了防止攻击
+ \-e 携带密码等参数
+ \-d 后台运行容器
+ \--auth MongoDB 进行权限校验
4、进入容器
```bash
docker exec -it mongodb mongo admin
```
> 注意: rpc error: code = 2 desc = oci runtime error: exec failed: container\_linux.go:235: starting container process caused “exec: “mongo”: executable file not found in $PATH”. 如果出现上述报错,是下载的 mongodb 镜像版本比较高,mongodb 5.0 以上的版本需要使用 mongosh命令来代替原来的 mongo 命令。 docker exec -it mongodb mongosh admin
5、验证用户名密码登录 返回 1 代表登录成功。
```arduino
db.auth('root', 'Admin123!@#')
```
![](https://img.blogweb.cn/article/63bcaafef19b4322a5ca96fa1fce42c3.webp)
6、使用数据库
```perl
use landingDB
```
7、创建数据库的管理员
```php
db.createUser({ user: "landing-user", pwd: "landing-admin.1234", roles: [{ role: "readWrite", db: "landingDB" }] })
```
MongoDB 不允许同一窗口有多个用户登录,退出再次进入终端:
```arduino
db.auth('landing-user', 'landing-admin.1234')
```
8、创建表
```arduino
db.createCollection('article')
db.createCollection('tag')
```
9、测试插入数据
```php
db.article.insert({ id: 1, title: '测试文章标题' })
```
10、通过 MongoDB Compass 连接数据库
```bash
mongodb://landing-user:landing-admin.1234@127.0.0.1:27019/landingDB
```
![](https://img.blogweb.cn/article/7dd8e15babde481b8cf123b2eac7c7b5.webp) ![](https://img.blogweb.cn/article/5401d7230cda4182abf1c6648ada78c5.webp)
### 编写 node 服务
1、借助 koa2 启动 node 服务
```js
// 引入模块
const Koa = require('koa')
const schedule = require('node-schedule')
// 实例化
const app = new Koa()
const main = async () => {
await initDB()
// 保存文章列表
const articleList = await getJueJinArticleList()
await insertArticles(articleList)
// 保存标签列表
const tagList = getTagList(articleList)
await insertTags(tagList)
}
app.listen(envJson.appPort, () => {
console.log(`app runs on port ${ envJson.appPort }`)
schedule.scheduleJob(cron, main)
})
```
2、将查询的数据存入数据库,并处理历史数据
```js
const { MongoClient } = require('mongodb')
const url = `mongodb://${username}:${password}@${host}:${port}/${dbName}`
const client = new MongoClient(url)
// 初始化数据库链接
const initDB = async () => {
await client.connect()
console.log('Connected successfully to mongodb')
}
// 新增查询到的文章列表
const insertArticles = async (articleList) => {
const db = client.db(dbName)
const collection = db.collection('article')
const updateResult = await collection.updateMany({ isDelete: 0 }, { $set: { isDelete: 1, updateTime: getDateStr() } })
console.log('updateArticles documents =>', updateResult)
const insertResult = await collection.insertMany(articleList)
console.log('insertArticles documents =>', insertResult)
}
```
![](https://img.blogweb.cn/article/026b38209d95453d8d62578592f56552.webp)
3、提供接口,从数据库读取数据 [接口文档](https://www.apifox.cn/apidoc/shared-c119f3d8-9f58-48bd-9584-0ed56c50d653)
```ini
const Router = require('koa-router')
const router = new Router()
router.get('/api/getTagList', async (ctx) => {
try {
const db = client.db(dbName)
const collection = db.collection('tag')
const data = await collection.find({ isDelete: 0 }).toArray()
ctx.body = {
code: 200,
data,
message: '成功',
}
} catch (error) {
ctx.body = {
code: 1,
error
}
}
})
```
### 编写页面
1、页面请求接口,拿到文章数据进行渲染,在标签、分页等参数变化时重新请求接口
```scss
useEffect(() => {
const params = {
page,
pageSize,
tag_id,
sort_type,
}
fetch(`/api/getArticleList?${new URLSearchParams(params).toString()}`)
.then(res => res.json())
.then(res => {
const { articleList, total } = res.data
setArticleList(articleList || [])
setTotal(total || [])
})
}, [tag_id, sort_type, page])
```
## 部署方式
一台 CentOS 服务器,安装 node 14+,pnpm,pm2,Docker(可选),MongoDB,nginx。
```bash
mkdir -p /opt/dtstack
git clone https://github.com/DTStack/UED.git
cd UED
pnpm i
pnpm deploy
```
因为后端服务的接口一般不对外暴露,此处通过 nginx 进行转发:
```bash
# ued landing 的 nginx 配置
# http
server {
listen 80;
server_name ued.dtstack.cn;
location / {
proxy_pass http://localhost:3004/;
}
location /api {
proxy_pass http://localhost:3002/api;
}
}
```
## 实现效果
[ued.dtstack.cn/article](http://ued.dtstack.cn/article)
![](https://img.blogweb.cn/article/bdd324698c84466eaf570363de89e09f.webp)
转载自:https://juejin.cn/post/7167255105257865229