一.获取全部qq成员头像
import os,requests,pymongo
class Qqgroup(object):#定义一个类
#定义获取QQ群的请求rul,抓包获取
group_rul = 'https://qun.qq.com/cgi-bin/qun_mgr/get_group_list'
#定义获取某个群的url,抓包获取
serach_url = 'https://qun.qq.com/cgi-bin/qun_mgr/search_group_members'
#定义获取图片的地址,抓包获取,将nk的值替换为%s,方便后面拼接
img_url = 'http://q4.qlogo.cn/g?b=qq&nk=%s&s=140'
def __init__(self,cookie):#构造函数,先把需要事先执行的写在这里
self.cookie = cookie#传入的cookie
#连接mongodb
self.client = pymongo.MongoClient(host='118.24.3.40',port=27017)
self.db = self.client['qq_group']#连接mongodb中的一个库,如果没有则新建
self.table = self.db['qq_group_wjp']#连接库中的表,没有则新建
def get_all_group(self):#定义一个函数用于获取qq群号码
data = {'bkn':1112777603}#请求中要传入的数据,抓包获取
#请求url,其中包括url,data,cookie,返回一个json格式的数据
#注意cookie不能直接写self.cookie,而要写成headers={'cookie':self.cookie}
res = requests.post(self.group_rul,data,headers={'cookie':self.cookie}).json()
#在获取的结果中取得所有的群,如果没有创建者默认为空,不是管理员默认为空
#在获得的群join,creat,manager的后面加上[],表示如果没有默认为空,
all_groups = res.get('join',[]) + res.get('creat',[]) + res.get('manager',[])
#使用列表生成式取得请求中的全部qq群号码gc(返回的数据中gc代表群号码)
all_gc = [i.get('gc') for i in all_groups]
print(all_gc)
return all_gc
# 定义一个函数获取qq群的qq号码(uin)性别(gender)和群名片(card),需要传入一个QQ群号码
#同样需要构建请求,所有数据都抓包获得
def get_mem_info(self,qq_num):
#构建请求中需要的参数,其中bkn为固定值,故类常量中已经定义,注意字典中应该使用双引号("")
data = {"gc": qq_num, "st": 0, "end": 1000, "sort": 0, "bkn": 1112777603}
#执行post请求,返回一个josn格式值
res = requests.post(self.serach_url, data, headers={'cookie': self.cookie}).json()
mems = res.get("mems") #从请求结果res中获得所有群成员的信息
for i in mems:#循环获得群成员信息
#构建一个字典men存放循环取得所需要的数据(uni代表qq号码,g代表性别,card代表群名片)
#i.get("xxx")表示从循环中获取的值
mem = {
"qq":i.get("uin"),
"gender":i.get("g"),
"nick":i.get("nick"),
"card":i.get("card"),
"qage":i.get("qage")
}
# 判断性别gender
if mem.get("gender") == 1:#如果获得gender=1
mem['gender'] = "男"#就将字典mem中gender的值改为'男'
elif mem.get("gender") == 0:#如果获得gender=0
mem['gender'] = "女"#就将字典mem中gender的值改为'女'
else:#否则
mem['gender'] = "未知性别"#就将字典mem中gender的值改为'未知性别'
#判断群名片card
if mem.get("card") == "":#如果数据中card的值为空
mem['card'] = "没有群名片"#就将该值设定为"没有群名片"
self.save_mongo(mem)#调用存储mongo的函数,将最后的值存放到mongodb
self.down_qq_pic(i.get("uin"))#调用下载qq头像的函数
#定义函数将传入的数据存放到mongodb
def save_mongo(self,data):
self.table.insert(data)#在mongo表table中插入传入的数据
print('插入成功')
#定义函数下载qq头像,
def down_qq_pic(self,qq_num):#传入参数QQ号码
real_url = self.img_url%qq_num#将传入的qq号码和类常量中的img_url拼接好
res = requests.get(real_url).content#执行get请求,返回二进制的数据
if not os.path.isdir('imgs'):#判断imgs如果不存在
os.mkdir('imgs')#就创建一个目录imgs
#将qq号码(qq_num)和(.jpg)拼接到一起插入到创建好的目录(imgs)中
#将上一步的文件使用with open和wb的形式赋值到fw
with open(os.path.join('imgs',str(qq_num)+'.jpg'),'wb') as fw:
fw.write(res)#将执行get请求结果写入打开的文件fw中
print('%s头像下载完成'%qq_num)#输出.....
#定义一个main方法,程序运行的入口
def main(self):
all_group = self.get_all_group()#调用get_qq_group方法赋值到all_group中(获取到全部的群号)
for group in all_group:#循环all_group(群号)
self.get_mem_info(group)#调用get_all_group方法,并将群号传入
cookie = 'xxxxx'
aa = Qqgroup(cookie)
# aa.get_all_group()
# aa.get_mem_info('248338124')
aa.main()
二.析构函数(def __del__),实例被销毁的时候执行(实例被删除的时候),也就是程序最后执行的.作用:在断开数据库链接,端口文件打开的时候使用,把关闭的代码写在该函数中
三.私有函数(def __car()),在函数前面加上两根下划线叫私有函数,只能在所在的类中使用
三.类方法,用类可以直接调用(My.eat()),实例化也可以调用.可以使用类变量cls.xxx,实例也可以通过self.xxx来使用类方法
四.静态方法,一个静态函数,只是定义在类里面而已,用不了实例方法和类方法,类变量,直接用类名调用
五.属性方法(@property).看起来像变量的函数,不能有入参,使用的时候直接用.方法名(.red_pag),获取到函数的返回值,没有返回值就获取到None
六.继承,子类继承父类的属性和方法,目的是为了简化代码,.修改父类方法就调用父类方法,其中Base .__init__(self,ip,port)=super().__init__(ip,port).父类的方法都可以用super().方法名(参数)来调用和修改原来方法
方法调用中 m = My()实列化后调用类中方法m.asy(),就等于My.say(m)
七.测试环境的搭建
第一次搭建,
1.安装依赖软件如,MySQL,redis,tomcat,nginx,jdx,pthon等,数据库,中间件;
2.获取代码,一般存在svn或者git上;
3.编译java,c(解释型语言不需要编辑python,php);
4.导入基础数据;
5.修改配置文件
6.启动项目
八.多线程,一个进程就是一个程序,线程就是进程中的最小执行单位,线程在进程里面,一个进程中最少有一个线程,线程之间是相互独立的,
用
while throeading.active_count()!=1 :
pass
来判断活动的线程数,如果不等于1就循环,如果等于1就释放
九.锁,多线程操作统一数据时,最好加上锁
十.线程池,为了防止系统运行的时候,起了过多的线程,首先导入threadpool,在创建一个线程连接数pool = threadpool.TheardPool(200),下面截图中主要说明使用使用多线程获取mongo中存的qq号来下载对应qq头像
十一.多进程,其用法是固定的,下图使用多进程下载QQ头像
十二.多线程适用于IO密集型任务,如磁盘 io,网络 io,多进程适用于CPU密集型任务,如排序