前言
在上一篇文章中,我们主要介绍了整个框架的基本架构,如果没看过的小伙伴,可以跳转链接打造一个轻量级分布式企业基本信息采集框架(一)
今天我们主要编写数据库这一块,包含mysql数据库存储部分以及redis数据库操作部分。
数据库
mysql
首先我们设计录入的mysql数据表,比较简单,写个sql语句就好了。
// 创建mysql数据库 名字叫epreg_collect
CREATE DATABASE IF NOT EXISTS epreg_collect default charset utf8 COLLATE utf8_general_ci
// 创建数据表
CREATE TABLE `qggs_app_collectlist` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`guid` varchar(64) DEFAULT NULL,
`pripid` varchar(256) DEFAULT NULL,
`entName` varchar(256) DEFAULT NULL COMMENT '企业名称',
`regNo` varchar(64) DEFAULT NULL COMMENT '注册号',
`uniscId` varchar(64) DEFAULT NULL COMMENT '统一代码',
`legelRep` varchar(64) DEFAULT NULL COMMENT '法定代表人',
`entTypeCn` varchar(128) DEFAULT NULL COMMENT '注册类型',
`corpStatusString` varchar(64) DEFAULT NULL COMMENT '企业状态',
`estDate` varchar(64) DEFAULT NULL COMMENT '注册日期',
`regOrg` varchar(256) DEFAULT NULL COMMENT '登记机关',
`busExceptCount` varchar(64) DEFAULT NULL,
`illCount` varchar(64) DEFAULT NULL,
`nodeNum` varchar(64) DEFAULT NULL,
`historyName` varchar(512) DEFAULT NULL,
`entType` varchar(64) DEFAULT NULL,
`collectstatus` varchar(32) DEFAULT NULL,
`json_data` longblob,
PRIMARY KEY (`id`),
KEY `entName` (`entName`),
KEY `regNo` (`regNo`),
KEY `uniscId` (`uniscId`),
KEY `entName_2` (`entName`),
KEY `guid` (`guid`),
KEY `uniscId_2` (`uniscId`),
KEY `entName_3` (`entName`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
// 主要的几个字段 comment上面已经标注了,sql这一块我就不多讲了,如果还不会,自行百度
上面是创建存储表,其中有几个字段需要说下,guid是我自己创建的uuid,用来标识唯一性,pripid是返回值自带的数据,用来请求详细页面用到的id(我们不请求详细页面),json_data是返回json,用二进制存储,其余的都没啥了。
class DbCollect:
def __init__(self):
self.db = MYSQL_DB
self.user = MYSQL_USER
self.passwd = MYSQL_PASSWORD
self.host = MYSQL_HOST
self.port = MYSQL_PORT
self.conn = pymysql.connect(host=self.host, user=self.user, password=self.passwd, port=self.port, db=self.db,
charset="utf8")
self.cur = self.conn.cursor()
self.client = RedisDbConn()
def connect_db(self):
"""
链接数据库,并且获取数据库内已有的keywords
:return: 关键词列表 list
"""
self.cur.execute("select keyword from qggs_app_keywords limit 100")
keywords_list = [row[0] for row in self.cur.fetchall()]
return keywords_list
def insert_basicsql(self, tbname, params):
"""
插入数据到数据库
:param tbname: 要插入的数据表名称
:param params: 字段的字典形式
"""
self.client.initial_set(str(params),PARAMS_REDIS_DB)
lists = [(k, params[k]) for k in params if params[k]]
sentence = 'insert into %s (' % tbname + ','.join([i[0] for i in lists]) + ') values (' + ','.join(
['%r' % i[1] for i in lists]) + ');'
self.cur.execute(sentence)
async def insert_detailsql(self, tbname, params,ori_params):
"""
插入数据到数据库
:param tbname: 要插入的数据表名称
:param params: 字段的字典形式
"""
lists = [(k, params[k]) for k in params if params[k]]
sentence = 'insert into %s (' % tbname + ','.join([i[0] for i in lists]) + ') values (' + ','.join(
['%r' % i[1] for i in lists]) + ');'
self.cur.execute(sentence)
self.client.set_success(PARAMS_REDIS_DB,ori_params)
首先初始化,导入pymysql,账号密码等都放在了config.py文件内,方便修改。创建一个游标用来操作mysql数据库。
connect_db() 这个函数当初设计是从原先的keywords数据库内获取keywords,后面想想,还是手动输入便于开始的测试采集。
insert_basicsql() 录入基础信息表。
insert_detailsql() 这个是录入详细表,详细页面的数据采集我是用的aiohttp,用的异步请求,这个函数可以略过。
Redis
选择的是用redis数据库zset集合来调度处理数据,首先是自动去重,其次是zset有个打分标签,相当于对每一个关键词打上一个标签,用于标注其采集状态。还有就是redis存储方便,基于内存,速度快(主要是看上这个)。
下面先把redis代码给上,再讲解。
class RedisDbConn:
def __init__(self):
pool = redis.ConnectionPool(host=REDIS_HOST, port=REDIS_PORT)
self.client = redis.Redis(connection_pool=pool)
# self.client = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT)
def get_data(self, status,key=KEYWORDS_REDIS_DB):
"""
判断redis中keywords
:param status: 状态码
:return: keywords list
"""
return self.client.zrangebyscore(key, status, status)
def get_count(self, status,key=KEYWORDS_REDIS_DB):
"""
获取数量
:param status: 状态码
:return: 数量
"""
return self.client.zcount(key, status, status)
def exists_keyword(self, keyword,key=KEYWORDS_REDIS_DB):
"""
判断关键词是否在库内
:param keyword: 关键词
:return: 值
"""
return True if self.client.zrank(key, keyword) else False
def set_success(self, keyword,key=KEYWORDS_REDIS_DB):
"""
将keywords设置为已采集标签 1
:param keyword: 关键字
:return: 是否成功设置
"""
if isinstance(keyword, str):
self.client.zadd(key, {keyword: SUCCESS_STATUS})
return True
def set_failure(self, keyword,key=KEYWORDS_REDIS_DB):
"""
将keywords设置为已失败采集标签 2
:param keyword: 关键字
:return: 是否成功设置
"""
if isinstance(keyword, str):
self.client.zadd(key, {keyword: FAILURE_STATUS})
return True
def initial_set(self, keyword,key=KEYWORDS_REDIS_DB):
"""
初始化设置,新进来的keywords设置为 0 未采集标签
:param keyword: 关键字
:return: 是否成功设置
"""
if not self.client.zscore(key, keyword):
self.client.zadd(key, {keyword: INIT_STATUS})
return True
def batch_keyword(self,start,stop,key=KEYWORDS_REDIS_DB):
"""
批量获取关键词,指定前几个
:param start: 开始索引
:param end: 结束索引
:return: 关键词列表
"""
result = self.client.zrevrange(key,start,stop)
return result
def del_db(self,key,status1=0,status2=0):
"""
删除指定状态的数据,不指定为0
:param key: redis zset
:param status1: 开始状态
:param status2: 结束状态
:return:
"""
self.client.zremrangebyscore(key,status1,status2)
return
自行"pip install redis",代码上面都给了一定的标注,我主要梳理下这一块的函数。首先创建RedisDbConn这个类,调用redis.ConnectionPool这个方法创建一个链接池,最后创建一个redis对象,就可以用来操作redis zset基本命令了,至于zset基本命令解释请自行看官方文档,都有详细的介绍。
get_data() 这个函数是用来取值,指定status的范围可以取出zset集合内的所有值,返回的是一个列表。
get_count() 是获取集合内有多少数量,需要指定状态码,也就是0,1,2,。
set_success() 将keywords状态设置为1,即采集成功。
set_failure() 将keywords状态设置为2,即采集失败。
def initial_set() 将keywords状态设置为0 即初始化设置,还未采集的
主要用到的就是上面几个函数,这些代码都放在db_collect这个py文件内。
结尾
以上就是db_collect.py这个文件内的所有内容了,这个文件主要就是对数据库进行初始化,方便调用,代码都挺简单,可自行完善一下。下一篇文章将会介绍调度器如何工作,敬请期待。打造一个轻量级分布式企业基本信息采集框架(三)