0x01 想法
这个想法也是很早之前有的了,一开始想做的高大尚一点做一个通用框架出来,但目前来看精力有限只能先把功能实现自己用着,目的是获取最新漏洞的消息,把消息做整理归档,预想有以下功能
定时爬取twitter网络安全相关消息内容,以后会增加其他网站内容
初步筛选内容
消息存储到服务器
通过前端展示消息,并可对消息做相关处理
消息展示时按照时间顺序展示
有了初步的想法利用一天的时间完成了以下工作。
完整项目代码在github https://github.com/ctlyz123/SecInfo
0x02 设计
打算自己编写通用型爬虫,毕竟以后要做大一点。数据规模不是很大,数据库目前采用mongodb。前端用vue element-ui编写,后端利用python flask 框架编写。
整个项目按照需求大体分为两个功能
动态从twitter上获取关于cve相关信息
制作展示前端和后端方便阅览及整理
0x1 爬虫
定时调用爬虫,将爬取的数据存到数据库中。但在实际的设计中也遇到了问题,比如太快的把消息移动到trash中会使得,短时间内下次爬取的数据是之前看过的,使得消息冗余。在实现的章节也提到了解决方法。
0x2 数据库
采用MongoDB数据库,总共设计两个数据表,分别存储已经未看过和已经看过的
twitter 负责存储未看条目
twitter_trash 负责已看条目
0x3 前端
一开始打算利用html+flask jinja做前端,后来想了想vue挺美观的而且部署更方便,于是就开启了爬坑之旅。vue一开始入坑的时候是在写基金分析平台,但是那个时候用的是iview框架,最后利用build指令的时候除了点小问题现在还在解决,所以这次就选用轻量级的element-ui组件编写。
0x4 后端
利用flask编写,后端功能比较简单,主要与mongodb交互。
0x03 实现
0x1 爬虫实现
爬虫实现是特别关注了当未读数据量过大的处理超时问题,特意将已经读过的消息放入到trash数据库中,减少twitter数据的查询压力,并且设置了hash缓冲区,防止阅读过后的消息短时间内再次出现。爬虫的处理逻辑大致为:
0x2 数据库实现
直接采用的docker MongoDB,创建以下库和表
> use secinfo
switched to db secinfo
> show tables
twitter
twitter_trash
相关数据库操作
db.twitter_trash.createIndex({hash:1},{unique:true}) //设置hash键为唯一键
db.twitter_trash.find().forEach(function(d){ db.getSiblingDB('secinfo')['twitter'].insert(d);})//数据库迁移把twitter_trash中的数据迁移到twitter数据库中
0x3 前端实现
1.生成vue项目
vue init webpack Client
2.安装element-ui
npm i element-ui -S
npm install --save axios
在 main.js 中写入以下内容
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App)
});
以上代码便完成了 Element 的引入。需要注意的是,样式文件需要单独引入。
3.选择模板
Element-ui模板 网站 https://element.eleme.cn/#/zh-CN/component/collapse
<template>
<el-collapse v-model="activeNames" @change="handleChange">
<template v-for="(value,hash,index) in sites" >
<el-collapse-item :title="value.time" :key="hash" ref="hash">
<div>{{value.content}}div>
<el-button @click="handledelete(hash)" type="danger" icon="el-icon-delete" circle>el-button>
el-collapse-item>
template>
el-collapse>
template>
<script>
前端同时设计了ajax异步发包和后台服务器交互,利用vue实时绑定的特性使得交互体验更棒。两个交互发包代码如下:
delete函数通过界面上的hash值进行删除,将返回的数据赋值给this.sites变量,当回调函数发现变量被改变时会触发一次渲染,这时候我们的界面就被更新了,这里有个坑我还没有爬出来如果不给this.sites赋值而是直接将其中的一个元素删除,是不会更新界面的,我认为是删除操作并没有触发回调。
handledelete (hash) {
axios.post("/delete",qs.stringify({hash:hash})).then((response) => {
if (response.data != "error") {
console.log(response.data)
this.sites = response.data
}
}).catch((response) => {
this.$Message.error({
content: '查询出错!' + response,
});
})
},
从flask获取数据源,并更新模板中的变量值。
handleshow () {
axios.get("/show").then((response) => {
if (response.data != "error") {
console.log(response.data)
this.sites = response.data
}
}).catch((response) => {
this.$Message.error({
content: '查询出错!' + response,
duration: 3,
});
})
}
0x4 后端实现
后端主要两个处理逻辑查询和删除
查询部分
查询出flag为0的消息
删除部分
首先更新选中消息的flag为0
将消息移动到trash中
删除在原表中的消息
@app.route('/delete',methods=['POST','GET'])
def delete():
hash = request.form.get('hash')
res = mongodb.update({"hash":hash},{"$set":{"flag":1}})
delete_one = mongodb.select({"hash":hash},{"_id":0})
try:
mongodb_trash.insert(delete_one)
mongodb.delete({"hash":hash})
except:
pass
return show()
@app.route('/show', methods=['POST', 'GET'])
def show():
a = mongodb.select_all({"flag":0},{"_id":0,"flag":0})
res = {}
for item in a:
res[item["hash"]] = item
resJson = jsonify(res)
return resJson
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9999)
0x04 部署
0x1 打包vue
这里没有其他特殊的配置,简单打包成dist文件夹。
npm run build
和flask代码整合在一起,在flask中添加以下代码,利用static_folder和template_folder设置静态资源目录。
app = Flask(import_name=__name__,
static_url_path='',
static_folder='../Client/dist',
template_folder='../Client/dist')
@app.route('/',methods=['POST','GET'])
def index():
return render_template('index.html')
0x2 crontab 定时爬虫
每30分钟执行爬虫主代码
HOME = /home/SecInfo/
*/30 * * * * python main.py
0x3 docker-compose
version: "3.3"
services:
mongodb:
image: mongo
privileged: true
tty: true
hostname: mongo
volumes:
- /tmp/share:/tmp/mongodb
secinfo:
build: secinfo
privileged: true
volumes:
- /tmp/share:/tmp/myfound
tty: true
hostname: SecInfo
ports:
- 9999:9999
links:
- mongodb
~