UED Landing 页 - 定时抓取掘金文章
我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。
本文作者:琉易 https://liuxianyu.cn
本次分享基于『袋鼠云数栈UED团队』新发布的 UED Landing 页 实践得来,UED Landing 页集合了团队目前所有的基础建设以及精选文章,是团队展现风采的一个地方。
项目基于 next.js、ts、pnpm、koa2、MongoDB 等技术方式实现,代码仓库:https://github.com/DTStack/UED,欢迎 star。
需求介绍
Landing 页有一个专栏页面,需要展示团队以往发在掘金社区的文章、对应的标签以及其他社区入口。
设计思路
基于上述的需求分析后,进行以下设计:
1、通过 node-schedule设置一个定时任务,每天去请求掘金的接口查询最新的文章数据,包括每篇文章的标题、发布人、阅读量、发布日期、标签等;
2、将上述方法拿到的数据处理后存入 MongoDB 数据库,只保留需要的字段;
3、提供一个 RESTful 风格的接口,分页返回文章列表和标签列表,供专栏页面查询使用;
4、页面请求接口,查询标签、文章数据 ,渲染页面。
实现步骤
以下实现步骤比较详细,类似的需求也可以按以下步骤去实现。
Docker 安装 MongoDB
1、下载镜像
docker pull mongo
2、创建挂载文件夹
mkdir -p /opt/dtstack/docker/mongo
cd /opt/dtstack/docker/mongo
3、启动容器
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、进入容器
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 代表登录成功。
db.auth('root', 'Admin123!@#')
6、使用数据库
use landingDB
7、创建数据库的管理员
db.createUser({ user: "landing-user", pwd: "landing-admin.1234", roles: [{ role: "readWrite", db: "landingDB" }] })
MongoDB 不允许同一窗口有多个用户登录,退出再次进入终端:
db.auth('landing-user', 'landing-admin.1234')
8、创建表
db.createCollection('article')
db.createCollection('tag')
9、测试插入数据
db.article.insert({ id: 1, title: '测试文章标题' })
10、通过 MongoDB Compass 连接数据库
mongodb://landing-user:landing-admin.1234@127.0.0.1:27019/landingDB
编写 node 服务
1、借助 koa2 启动 node 服务
服务入口处新建定时任务,每天去掘金获取文章数据
// 引入模块
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、将查询的数据存入数据库,并处理历史数据
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)
}
3、提供接口,从数据库读取数据
接口文档
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、页面请求接口,拿到文章数据进行渲染,在标签、分页等参数变化时重新请求接口
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。
mkdir -p /opt/dtstack
git clone https://github.com/DTStack/UED.git
cd UED
pnpm i
pnpm deploy
因为后端服务的接口一般不对外暴露,此处通过 nginx 进行转发:
# 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 Landing 页 - 定时抓取掘金文章的更多相关文章
- PowerShell定时抓取屏幕图像
昨天的博文写了定时记录操作系统行为,其实说白了就是抓取了击键的记录和对应窗口的标题栏,而很多应用程序标题栏又包含当时记录的文件路径和文件名,用这种方式可以大致记录操作了哪些程序,打开了哪些文 ...
- 基于Node.js的强大爬虫 能直接发布抓取的文章哦
基于Node.js的强大爬虫 能直接发布抓取的文章哦 基于Node.js的强大爬虫能直接发布抓取的文章哦!本爬虫源码基于WTFPL协议,感兴趣的小伙伴们可以参考一下 一.环境配置 1)搞一台服务器,什 ...
- 一篇文章教会你使用Python定时抓取微博评论
[Part1--理论篇] 试想一个问题,如果我们要抓取某个微博大V微博的评论数据,应该怎么实现呢?最简单的做法就是找到微博评论数据接口,然后通过改变参数来获取最新数据并保存.首先从微博api寻找抓取评 ...
- [Python爬虫] 之十五:Selenium +phantomjs根据微信公众号抓取微信文章
借助搜索微信搜索引擎进行抓取 抓取过程 1.首先在搜狗的微信搜索页面测试一下,这样能够让我们的思路更加清晰 在搜索引擎上使用微信公众号英文名进行“搜公众号”操作(因为公众号英文名是公众号唯一的,而中文 ...
- 使用redis所维护的代理池抓取微信文章
搜狗搜索可以直接搜索微信文章,本次就是利用搜狗搜搜出微信文章,获得详细的文章url来得到文章的信息.并把我们感兴趣的内容存入到mongodb中. 因为搜狗搜索微信文章的反爬虫比较强,经常封IP,所以要 ...
- python抓取头条文章
python抓取头条美文并存储到mongodb # Author:song from multiprocessing import Pool from urllib.parse import urle ...
- asp.net MVC 抓取微信文章数据(正文)
1.抓微信的正文主要是调用第三方的接口(https://market.aliyun.com/products/56928004/cmapi012134.html) using Newtonsoft.J ...
- 抓取天涯文章的蜘蛛代码,刚经过更新(因为天涯页面HTML代码变化)
#_*_coding:utf-8-*- import urllib2 import traceback import codecs from BeautifulSoup import Beautifu ...
- asp.net mvc抓取微信文章里面所有的图片
/// <summary> /// 下载指定URL下的所有图片 /// </summary> public class WebPageImage { /// <summa ...
- 如何使用 Github Actions 自动抓取每日必应壁纸?
如何白嫖 Github 服务器自动抓取必应搜索的每日壁纸呢? 如果你访问过必应搜索网站,那么你一定会被搜索页面的壁纸吸引,必应搜索的壁纸每日不同,自动更换,十分精美.这篇文章会介绍如何一步步分析出必应 ...
随机推荐
- Linux有趣命令
通外网 下载使用阿里云镜像源:wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.re ...
- KingbaseES 开启事务提交跟踪
KingbaseESV8R6有个参数 track_commit_timestamp,用来开启跟踪事务提交的时间戳. 配置 编辑kingbase.conf,添加配置如下: track_commit_ti ...
- ubuntu下vscode安装go插件失败解决办法
go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.io,direct go env -w GOSUMDB=gosum.io+ce6e ...
- uniapp scroll-view组件隐藏滚动条
在pages.json增加如下配置 "globalStyle": { "navigationBarTextStyle": "black", ...
- Go工程化 - 依赖注入
我们在微服务框架kratos v2的默认项目模板中kratos-layout使用了google/wire进行依赖注入,也建议开发者在维护项目时使用该工具. wire 乍看起来比较违反直觉,导致很多同学 ...
- Kubernetes 日志:搭建 EFK 日志系统
Kubernetes 中比较流行的日志收集解决方案是 Elasticsearch.Fluentd 和 Kibana(EFK)技术栈,也是官方现在比较推荐的一种方案. Elasticsearch 是一个 ...
- 1.Ceph 基础篇 - 存储基础及架构介绍
文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247485232&idx=1&sn=ff0e93b9 ...
- mysql8数据库修改root密码,以及创建用户遇到的坑,开启远程登录,用navicat进行mysql的远程连接,mysql8.0默认编码方式,部分参数配置查询命令
yum 安装MySQL8 echo "删除系统默认或之前可能安装的其他版本的 mysql" for i in $(rpm -qa|grep mysql);do rpm -e $i ...
- C语言:类型存储
类型存储 char: 可能为signed char 或 unsigned char ,根据编译器不同实现不同.占位一个字节.Signed char取值范围为-128~127, unsigned cha ...
- 通过js实现随机生成图片
这次给大家分享一个通过js向HTML添加便签,实现随机代码生成的案例,代码已经放在下方,这里我在下面准备了50张图片,但是没有放在博文中,如果读者想要练习,可以自己下载一些图片,建议下载的多一些. & ...