目录
前言:
今天是入职第一天,被技术经理分配工作:写一个Cookie池接口
Cookie池要求:
1、要有一个保存cookie的接口,保存文档不限制,存入mysql,txt文本,redis都行
2、要有一个提取cooike的接口
3、要给cookie加一个“有效时间”的属性,并且Cookie池可以清除掉超时的cookie
4、要留出足够的扩展空间,方便后面的拓展开发
9点到公司报道,弄清后10点多了,到12点一直在构思怎么简洁快速的完成任务,最后决定使用mysql数据库作为存储,下午开始写代码,于是乎有了第一个版本,如下
第一天修改
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import redis,time,json,pymysql
# from pymysql
class CookDea:
'''
初始化数据库连接
:param host:数据库IP地址
:param port:数据库端口
:param database:所使用数据库
:param user:连接用户名
:param password:连接密码
'''
def __init__(self, host, port, database, user, password, charset="utf8"):
# 连接数据库
self.db = pymysql.connect(host=host, port=port, database=database, user=user, password=password, charset=charset,)
self.cursor = self.db.cursor()# 创建游标对象
# self.table_name = table_name
'''
根据table_name和data在数据库建立相应的表
'''
def create_table(self, table_name, data):
data = data.copy()
try:
data.pop("cookies")
except:
pass
sql_add="".join('{} varchar(2000) DEFAULT NULL,'.format(k) for k in data.keys())
self.cursor.execute('''CREATE TABLE IF Not EXISTS `{}` (
`id` int(10) NOT NULL AUTO_INCREMENT, {}
`cookies` varchar(2000) DEFAULT NULL,
`beg_time` int(20) DEFAULT NULL,
`end_time` int(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;'''.format(table_name,sql_add))
'''
保存cookies信息到数据库
:param table_name:表名
:param data:cookies数据,格式如:{"province":"浙江", "tax": "1", "cookies":"{"user":"123"}" }
:param alive_time:cookies有效时间(单位-秒)
注意:如果未创建数据表,请使用create_table(self, table_name, data)创建数据表
'''
def save(self, table_name, data, alive_time=3600):
beg_time = int(time.time())
data["beg_time"]=beg_time
data["end_time"]=beg_time+alive_time
self.__insert(table_name, data)
result = self.__update(table_name, data)
if result==0:
result = self.__insert(table_name, data)
return result
'''
获取相应条件下的随机一条cookies信息
:param table_name:表名
:param data:格式为{"province":"浙江","tax": "1"},表示查询province为浙江且tax为1的一条数据
'''
def get_one(self, table_name, data):
return self.__select( table_name, data)
'''
数据库插入操作
:param table_name:表名
:param data:插入数据
'''
def __insert(self, table_name, data):
sql = "insert into {}(%s) values(%s)".format(table_name)
res_sql = sql % (", ".join('`{}`'.format(k) for k in data.keys()), ', '.join('%({})s'.format(k) for k in data.keys()))
self.cursor.execute(res_sql, data) # 将字典data传入
self.db.commit()
'''
数据库更新操作
:param table_name:表名
:param data:更新数据
'''
def __update(self, table_name, data):
print("此处待修改~~~~~~~")
return 0
sql_add = " AND ".join("`" + key + "`='" + value + "'" for key, value in data.items())
sql = "UPDATE {} SET {} WHERE cookies={};".format(table_name, sql_add, data["cookies"])
print("sql:", sql)
self.cursor.execute(sql) # 将字典data传入
self.db.commit()
'''
数据库查询操作
:param table_name:表名
:param data:查询条件,格式为{"province":"浙江","tax": "1"},表示查询province为浙江且tax为1的一条数据
'''
def __select(self, table_name, data):
try:
sql_add = " AND ".join("`" + key + "`='" + value + "'"for key, value in data.items())
self.cursor.execute("SELECT * FROM {} WHERE {} ORDER BY RAND() LIMIT 1;".format(table_name,sql_add))
res = self.cursor.fetchone()
# now_time = int(time.time())
return res
except:
return None
'''
删除相应条件下的cookies
:param table_name:表名
:param data:格式为{"province":"浙江","tax": "1"},表示清除province为浙江且tax为1的cookies数据
:param orer_time:是否只清除超时的数据?1:是 0:否
'''
def clear(self, table_name, data, orer_time=1):
sql_add = " AND ".join("`" + key + "`='" + value + "'" for key, value in data.items())
sql = "DELETE FROM {} WHERE {} AND `end_time`>{};".format(table_name, sql_add, int(time.time())) if orer_time==1 \
else "DELETE FROM {} WHERE {} ;".format(table_name, sql_add)
print(sql)
result = self.cursor.execute(sql)
self.db.commit()
return result
if __name__ == '__main__':
url = "https://www.cnblogs.com"
cookies = {'_ga': 'GA1.2.368799281.1551860816', '__gads': 'ID',
'Hm_lvt_159f5d3f9ae2bd304b8e99efa2e9ae34': '1551884072,1551937443',
'Hm_lpvt_159f5d3f9ae2bd304b8e99efa2e9ae34': '1551937443',
'sc_is_visitor_unique': 'rx11644382.1553693305.EBA7A35830044F4743585FA345B2D54D.1.1.1.1.1.1.1.1.1',}
data = {"province": "浙江3333333",
"tax": "1",
"cookies": json.dumps(cookies)
}
ck = CookDea("localhost",3306,"testx1","root","root")
ck.create_table("cookies_pool",data)
# ck.save("cookies_pool",data)
# data["province"] = "北京"
print(ck.save("cookies_pool",data))
ck.get_one("cookies_pool",{"province":"浙江","tax": "0",})
# print(ck.clear("cookies_pool",{"province":"北京2","tax": "1",},0))
其中create_table(self, table_name, data)可以根据data字典在数据库创建相应的数据表,然后可以利用__insert(self, table_name, data)插入相应的data字典数据,可以说非常灵活。(提示,如果看不懂代码的SQL操作,可以看看我之前的博客:Python中pymysql通过字典插入数据)
“你怎么保证cookie数据的唯一性?所以你可以加个cookieID作为cookie数据标识,也可以对重要的属性进行哈希处理作为唯一主键”,这是大佬和我说的话,其中还有一些PEP8的格式问题就不一一说了,于是乎,第二天开始了新的修改,代码如下:
第二天修改
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import time,json,os
import hashlib
try:
import pymysql
except:
os.system("pip install pymysql")
class CookieClass:
def __init__(self,province,tax,cookies):
self.province = province
self.tax = str(tax)
self.cookies = str(cookies)#(cookies为必有属性-不可删)
# 可将唯一对应属性进行md5处理,__md5_deal()可接收多个参数(md5为必有属性-不可删)
self.md5 = self.__md5_deal(tax)
'''
对接受的参数进行md5处理,并返回处理值
:return:返回md5处理值
'''
def __md5_deal(self, *args):
txt = "".join([str(i) for i in args])
md = hashlib.md5()
md.update(txt.encode())
return md.hexdigest()
class CookDea:
'''
初始化数据库连接
:param host:数据库IP地址
:param port:数据库端口
:param database:所使用数据库
:param user:连接用户名
:param password:连接密码
'''
def __init__(self, host, port, database, user, password, charset="utf8"):
# 连接数据库
self.db = pymysql.connect(host=host, port=port, database=database, user=user, password=password, charset=charset,)
self.cursor = self.db.cursor()# 创建游标对象
# self.table_name = table_name
'''
根据table_name和data在数据库建立相应的表
:return:返回sql结果值
'''
def create_table(self, table_name, cookie_class):
data = cookie_class.__dict__
data = data.copy()
try:
data.pop("cookies")
data.pop("md5")
except:
pass
sql_add="".join('`{}` varchar(2000) DEFAULT NULL,'.format(k) for k in data.keys())
result = self.cursor.execute('''CREATE TABLE IF NOT EXISTS `{}` (
`md5` varchar(200) NOT NULL, {}
`cookies` varchar(2000) DEFAULT NULL,
`beg_time` int(20) DEFAULT NULL,
`end_time` int(20) DEFAULT NULL,
PRIMARY KEY (`md5`)
) DEFAULT CHARSET=utf8;'''.format(table_name,sql_add))
return result
'''
保存cookies信息到数据库
:param table_name:表名
:param data:cookies数据,格式如:{"province":"浙江", "tax": "1234567", "cookies":"{"user":"123"}" }
:param alive_time:cookies有效时间(单位-秒)
注意:如果未创建数据表,请使用create_table(self, table_name, data)创建数据表
:return:返回sql保存结果值
'''
def save(self, table_name, cookie_class, alive_time=3600):
data = cookie_class.__dict__
beg_time = int(time.time())
data["beg_time"]=beg_time
data["end_time"]=beg_time+alive_time
result = self.__update(table_name, data)
if result==0:
result = self.__insert(table_name, data)
return result
'''
获取相应条件下的随机一条cookies信息
:param table_name:表名
:param tax:税号
:return:返回查询结果
'''
def get_by_tax(self, table_name, tax):
self.cursor.execute("SELECT * FROM {} WHERE `tax`='{}' ".format(table_name, tax))
res = self.cursor.fetchone()
return res
'''
获取相应条件下的随机一条cookies信息
:param table_name:表名
:param province:省份
:return:返回查询结果
'''
def get_by_province(self, table_name, province):
self.cursor.execute("SELECT * FROM {} WHERE `province`='{}' ".format(table_name, province))
res = self.cursor.fetchone()
return res
'''
获取相应条件下的随机一条cookies信息
:param table_name:表名
: