强子本人比较喜欢研究各种营销工具,日常关注五二破姐社区,今天发现一个python爱好者@杨氏一个帖子“[原创工具] python获取Q群的信息数据100%用得到【已开源】”,于是就马上下载体验了下,可用有效。文章源自黄强博客-https://huangqiang.me/356.html
说起提取数据精准营销,早在2009年开始我们就在用了,一直很好用,当年做培训和后来开发销售淘客分佣系统的时候都用过,非常好用,因为QQ群可以根据关键词筛选加群,获取到的用户都是产品和服务的精准潜在客户,ROI那时候是相当的高了。文章源自黄强博客-https://huangqiang.me/356.html
时至今日,虽然营销界的风口热点在短视频和微信上,但也不影响老的有效方法依然有效。有数据统计,95后和00后用户使用QQ的时间要比微信多的多。文章源自黄强博客-https://huangqiang.me/356.html
及时微信是占用用户时间最多的应用,也不影响大家因为工作等原因,依然要依赖邮件和手机短信,剩下的可以发挥自己想象。文章源自黄强博客-https://huangqiang.me/356.html
分享前的申明
分享这些,只是从精准营销角度去分析操盘思路和流程,仅供大家参考学习。文章源自黄强博客-https://huangqiang.me/356.html
一切正规的产品和服务,通过本文分享的几种方法去做营销推广是一点问题都没有的,比如各大银行的促销邮件,新款游戏上线的推广等等。文章源自黄强博客-https://huangqiang.me/356.html
任何好的推广方式都不应该去做违法违规的事情,不值得。毕竟阳光正规的项目也遍地都是对吧~文章源自黄强博客-https://huangqiang.me/356.html
下面开始正式分享。文章源自黄强博客-https://huangqiang.me/356.html
亲测提取效果
文章源自黄强博客-https://huangqiang.me/356.html
这里获取到的数据还是很全面的,包含QQ昵称、群昵称、QQ号码、性别、Q龄、入群时间和最后发言时间(可以知道活跃状况)、手机号,区域城市、还有微博id。文章源自黄强博客-https://huangqiang.me/356.html
这里面可以使用的有效数据已经很全了,最有价值的就是昵称+qq号+手机号,至少可以通过EDM邮件营销、微信营销、短信营销 三大方式去做精准推送营销。文章源自黄强博客-https://huangqiang.me/356.html
这三种营销方式该怎么玩?
下面简单分享下可操作的几种方式。文章源自黄强博客-https://huangqiang.me/356.html
1、微信营销
目前用户活跃度最高的方式也就是微信了。文章源自黄强博客-https://huangqiang.me/356.html
可以利用提取到的qq号、手机号去批量检测用户是否开通微信,筛选出开通了微信的数据去加成微信好友,然后配合适当的广告话术定向精准的营销。文章源自黄强博客-https://huangqiang.me/356.html
2、短信营销
这个就不用多说了吧,获取到目标用户手机号后,可以通过短信群发定向的推送匹配用户的产品和服务广告。相比微信还少了加好友一个步骤,只需要创作好内容文案、找个靠谱的发送服务商推送即可。文章源自黄强博客-https://huangqiang.me/356.html
3、EDM营销营销
邮件是最古老的一种营销方式,也是成本相对较低,比较容易做出规模化的方式,俗话说量变可以引起质变,加上这种方式可以通过关键词、有计划的去筛选目标用户所在的QQ群加群,获得的客户数据还算是比较精准的潜在用户了,通过邮件可以很轻松的通知到数千数万乃至几十万百万潜在用户,再配合销售信软文文案,提高阅读率和转化率,每个流程都优化好的情况下这个结果也会是不错的。文章源自黄强博客-https://huangqiang.me/356.html
成品工具下载链接
补充说明
软件使用很简单,下载解压后,登录QQ并运行“QQ群信息获取.exe”主程序即可,剩下的看界面选择应该就会玩了。文章源自黄强博客-https://huangqiang.me/356.html
如果是会python的技术流,还可以自己去研究下开源代码,说不定还能diy出更多新功能玩法呢,如果你会这个编程语言,也喜欢专研,不妨来交流下,说不定还能碰撞延伸出更多好玩的方案。文章源自黄强博客-https://huangqiang.me/356.html
本工具为强子转载分享,还是非常感谢作者@杨氏的免费分享。文章源自黄强博客-https://huangqiang.me/356.html
QQ群数据提取工具python开源代码
import threading import tkinter as tk from tkinter import ttk from tkinter import * import tkinter.filedialog from tkinter import scrolledtext import requests from PIL import Image import time import re import emoji import json import math #import xlwt #导入excel官方模块,用于将字典生成excel import pandas as pd #将字典列表转换为DataFrame from tkinter import messagebox root = tk.Tk() #----------------------------登录功能函数-------------------------------- def bkn(Skey): t = 5381 n = 0 o = len(Skey) while n < o: t += (t << 5) + ord(Skey[n]) n += 1 return t & 2147483647 def ptqrtoken(qrsig): n = len(qrsig) i = 0 e = 0 while n > i: e += (e << 5) + ord(qrsig[i]) i += 1 return 2147483647 & e def QR(): url = 'https://ssl.ptlogin2.qq.com/ptqrshow?appid=715030901&e=2&l=M&s=3&d=72&v=4&t=0.'+str(time.time())+'&daid=73&pt_3rd_aid=0' r = requests.get(url) qrsig = requests.utils.dict_from_cookiejar(r.cookies).get('qrsig') with open(r'QQ.png','wb') as f: f.write(r.content) im = Image.open(r'QQ.png') im = im.resize((350,350)) # print('登录二维码获取成功',time.strftime('%Y-%m-%d %H:%M:%S')) im.show() return qrsig def cookies(qrsig,ptqrtoken): while 1: url = 'https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fqun.qq.com%2Fmanage.html%23click&ptqrtoken=' + str(ptqrtoken) + '&ptredirect=1&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-' + str(time.time()) + '&js_ver=20032614&js_type=1&login_sig=&pt_uistyle=40&aid=715030901&daid=73&' cookies = {'qrsig': qrsig} r = requests.get(url,cookies = cookies) r1 = r.text if '二维码未失效' in r1: # print('二维码未失效',time.strftime('%Y-%m-%d %H:%M:%S')) pass elif '二维码认证中' in r1: # print('二维码认证中',time.strftime('%Y-%m-%d %H:%M:%S')) pass elif '二维码已失效' in r1: # print('二维码已失效',time.strftime('%Y-%m-%d %H:%M:%S')) #重新获取二维码 # qrsig = QR() pass else: # print('登录成功',time.strftime('%Y-%m-%d %H:%M:%S')) cookies = requests.utils.dict_from_cookiejar(r.cookies) # print(cookies) uin = requests.utils.dict_from_cookiejar(r.cookies).get('uin') regex = re.compile(r'ptsigx=(.*?)&') sigx = re.findall(regex,r.text)[0] url = 'https://ptlogin2.qun.qq.com/check_sig?pttype=1&uin=' + uin + '&service=ptqrlogin&nodirect=0&ptsigx=' + sigx + '&s_url=https%3A%2F%2Fqun.qq.com%2Fmanage.html&f_url=&ptlang=2052&ptredirect=101&aid=715030901&daid=73&j_later=0&low_login_hour=0®master=0&pt_login_type=3&pt_aid=0&pt_aaid=16&pt_light=0&pt_3rd_aid=0' r2 = requests.get(url,cookies=cookies,allow_redirects=False) targetCookies = requests.utils.dict_from_cookiejar(r2.cookies) skey = requests.utils.dict_from_cookiejar(r2.cookies).get('skey') break time.sleep(3) return targetCookies,skey join_qun = {} create_qun = {} manage_qun = {} def qun(cookies,bkn,num): url = 'https://qun.qq.com/cgi-bin/qun_mgr/get_group_list' data = {'bkn':bkn} cookies = cookies # print(cookies) r = requests.post(url,data = data,cookies = cookies) #--------------------传出去一个res的值,用于后面获取群列表的操作---------------- res = r.text res = res.encode('utf-8', 'replace').decode() res1 = json.loads(res) global join_qun global create_qun global manage_qun if "create" in res1: create_qun = res1['create'] else: create_qun = {} if "join" in res1: join_qun = res1['join'] else: join_qun = {} if "manage" in res1: manage_qun = res1['manage'] else: manage_qun = {} #--------------------传出去一个res的值,用于后面获取群列表的操作---------------- regex = re.compile(r'"gc":(\d+),"gn') r = re.findall(regex,r.text) return cookies #----------------------------登录功能函数-------------------------------- #----------------------------群功能函数---------------------------------- def load_data(st,end):#加载数据需要传入st开始位置和end结束位置 url = 'https://qun.qq.com/cgi-bin/qun_mgr/search_group_members' def str_cookie(state): str1 = '' for i in state: str1 = str1 + i + '=' + state[i] + '; ' return str1 cookie = str_cookie(state) # print('cookie='+cookie) headers = { "cookie": cookie } def get_bkn():#从QQ群中获取bkn函数 e = state['skey'] t = 5381 n = 0 o = len(e) while n < o: t += (t << 5) + ord(e[n]) n += 1 return(2147483647 & t) # print(get_bkn()) # gc = input('请输入要查询的群号:') global gc gc = show_qqqun_number() #群号 data = { "gc": gc, "st": st, "end": end, "sort": "0", "bkn": get_bkn() } response = requests.post(url,data=data,headers=headers,verify=False ) response = response.text response = response.encode('utf-8').decode("unicode_escape") return response def get_qq_member_count():#获取群成员数量函数 response = load_data(0,0) qq_member_count = json.loads(response)['count'] #qq群人数 # print(qq_member_count) return qq_member_count qq_qun_info = [] def get_qq_member_list():#获取群成员列表函数 global qq_qun_info #全局变量qq群信息列表 qq_qun_info = [] count = math.ceil(get_qq_member_count()/21) #需要循环的次数 # print('需要循环的次数:'+str(count)) n = 0 #用于计数 j = 0 #计数器用于判断当前循环的次数 num = 1 #用于给字典里的信息加序号 while j < count: #load_data()参数的取值 第一次是从1到20 第二次是从21到42 第三次是从43到63以此类推保证不获取重复值 response = load_data(n+j,n+20+j) res = json.loads(response)['mems'] # print('res='+str(res)) qq_name = '' # qq名字 qq_qun_name = '' # qq群名字 qq_number = '' # qq号码 sex = '' # 性别 qq_age = '' #q龄 join_qun_time = '' # 入群时间 last_speak_time = '' # 最后一次发言 for i in res: qq_name = i['nick'] #替换qq昵称中的\为空 qq_name = filter_emoji(qq_name,'??????') qq_qun_name = i['card'] #替换qq群昵称中的\为空 qq_qun_name = filter_emoji(qq_qun_name,'??????') qq_number = str(i['uin']) sex = i['g'] #如果sex = 0则为男性, sex = -1未知, sex = 1为女性 if sex == 0: sex = '男' elif sex == 1: sex = '女' elif sex == -1: sex = '未知' else: sex = '错误' qq_age = i['qage'] join_qun_time = i['join_time'] #这里返回的是10位整数 last_speak_time = i['last_speak_time'] #将以上内容加入字典dict1中 dict1 = {} dict1['num'] = num dict1["qq_name"] = qq_name dict1["qq_qun_name"] = qq_qun_name dict1["qq_number"] = qq_number dict1["sex"] = sex dict1["qq_age"] = qq_age #将十位数入群时间转为正常时间 join_qun_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(join_qun_time)) dict1["join_qun_time"] = join_qun_time #将十位数最后一次发言时间转为正常时间 last_speak_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_speak_time)) dict1["last_speak_time"] = last_speak_time #将字典dict1加入列表qq_qun_info列表中 qq_qun_info.append(dict1) if select_var.get() == 0: table.insert('', 'end', values=(num, qq_name, qq_qun_name, qq_number, sex,qq_age,join_qun_time,last_speak_time)) #滚动到table的最下方 #打印输出日志 由于num是从1开始的 但是列表是从0计数,所以此处num-1 scroll.insert(END, "\n"+str(qq_qun_info[num-1])) scroll.see("end") # print(qq_qun_info[num-1]) num = num + 1 j = j + 1 n += 20 # print(qq_qun_info) member_count = get_qq_member_count() if member_count > 0: if(select_var.get() == 1):#选中 messagebox.showinfo('提示','查询到'+str(member_count)+'个好友数据,正在扫描后四位信息,此过程可能会比较漫长,请耐心等待...') from_qq_get_info() #调用查后四位数据的函数 messagebox.showinfo('提示','导入完成,一共导入'+str(member_count)+'个好友数据') else: messagebox.showinfo('提示','查询到'+str(member_count)+'个好友数据') else: messagebox.showinfo('提示','没有查询到任何好友数据') return qq_qun_info # print(qq_qun_info) #显示群成员列表 #利用qq号码获取更多信息,此方法耗时严重,不建议使用 def from_qq_get_info(): time.sleep(2) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36', } for i in qq_qun_info: response = requests.get(url,headers=headers) response = response.text response = json.loads(response) # print(response) if response['status'] == 200: qq_qun_info[qq_qun_info.index(i)]['phone'] = response['phone'] qq_qun_info[qq_qun_info.index(i)]['diqu'] = response['phonediqu'] qq_qun_info[qq_qun_info.index(i)]['lol'] = response['lol'] qq_qun_info[qq_qun_info.index(i)]['wb'] = response['wb'] else: qq_qun_info[qq_qun_info.index(i)]['phone'] = '未知' qq_qun_info[qq_qun_info.index(i)]['diqu'] = '未知' qq_qun_info[qq_qun_info.index(i)]['lol'] = '未知' qq_qun_info[qq_qun_info.index(i)]['wb'] = '未知' table.insert('', 'end', values=(i['num'], i['qq_name'], i['qq_qun_name'], i['qq_number'], i['sex'],i['qq_age'],i['join_qun_time'],i['last_speak_time'],i['phone'],i['diqu'],i['lol'],i['wb'])) def log(): scroll.insert(END, "\n"+str(qq_qun_info[qq_qun_info.index(i)])) scroll.see("end") # print(qq_qun_info[qq_qun_info.index(i)]) threading.Thread(target = log).start() def export_excel(export):#将qq_qun_info列表保存为excel函数 #将字典列表转换为DataFrame pf = pd.DataFrame(list(export)) #指定字段顺序 if select_var.get() == 1: order = ['num','qq_name','qq_qun_name','qq_number','sex','qq_age','join_qun_time','last_speak_time','phone','diqu','lol','wb'] else: order = ['num','qq_name','qq_qun_name','qq_number','sex','qq_age','join_qun_time','last_speak_time'] pf = pf[order] #将列名替换为中文 columns_map = { 'num':'序号', 'qq_name':'qq昵称', 'qq_qun_name':'qq群昵称', 'qq_number':'qq号码', 'sex':'性别', 'qq_age':'Q龄', 'join_qun_time':'入群时间', 'last_speak_time':'最近发言时间', 'phone':'手机号', 'diqu':'地区', 'lol':'lol', 'wb':'微博UID' } pf.rename(columns = columns_map,inplace = True) #指定生成的Excel表格名称 file_path = pd.ExcelWriter(save_path+'.xlsx') #替换空单元格 pf.fillna(' ',inplace = True) #输出 pf.to_excel(file_path,encoding = 'utf-8',index = False) #保存表格 file_path.save() #过滤特殊字符函数 def filter_emoji(desstr, restr=''): #desstr是要过滤的字符串 #restr是替换的字符串 # 过滤表情 res = re.compile(u'[\U00010000-\U0010ffff\\uD800-\\uDBFF\\uDC00-\\uDFFF]') return res.sub(restr, desstr) #----------------------------群功能函数---------------------------------- #----------------------------获取群列表---------------------------------- def get_allqun_list(group_name):####修改这里####修改这里####修改这里####修改这里####修改这里####修改这里 if group_name == '我创建的群': # print('create_qun:',create_qun) return create_qun if group_name == '我加入的群': # print('join_qun:',join_qun) return join_qun if group_name == '我管理的群': # print('manage_qun:',manage_qun) return manage_qun #----------------------------获取群列表---------------------------------- #----------------------------界面---------------------------------- label1 = tk.Label(root,text = 'QQ群号:') label1.place(x = 150,y = 10) label1.config(font = ('微软雅黑',12)) #-------------------------选择相应的分组---------------------------------- qq_qun_gc = [] qq_qun_gn = [] def show_group(*arg): global qq_qun_gc global qq_qun_gn qq_qun_gc = [] qq_qun_gn = [] all_qun1 = get_allqun_list(value_group.get()) # print(all_qun1) for i in all_qun1: qq_qun_gc.append(i['gc']) gn = emoji.demojize(i['gn']) gn = re.sub(emoji.get_emoji_regexp(), r"?", gn) gn = filter_emoji(gn,'?') qq_qun_gn.append(gn) # print(qq_qun_gc) # print(qq_qun_gn) #下拉列表框中的值 xiala_list["values"] = qq_qun_gn xiala_list.current(0) value_group = StringVar() #定义一个下拉列表 data_group = ["我创建的群","我管理的群","我加入的群"] # if create_qun =={}: # data_group.remove('我创建的群') # if join_qun =={}: # data_group.remove('我加入的群') # if manage_qun =={}: # data_group.remove('我管理的群') #创建一个下拉列表 group_list = ttk.Combobox(root, width = 10, height = 10, textvariable = value_group, state="readonly") #设置字体 group_list.config(font = ('微软雅黑',12)) group_list.bind("<<ComboboxSelected>>",show_group) #事件的绑定 group_list.place(x = 230, y = 10) #下拉列表框中的值 group_list["values"] = data_group #-------------------------选择相应的分组---------------------------------- #-------------------------对应分组的群号---------------------------------- def show_qqqun_number(*arg): index1 = xiala_list.current() qq_qun_num = qq_qun_gc[index1] # print(qq_qun_num) return qq_qun_num value = StringVar() #创建一个下拉列表 xiala_list = ttk.Combobox(root, width = 13, height = 10, textvariable = value) #设置字体 xiala_list.config(font = ('微软雅黑',12)) xiala_list.place(x = 360, y = 10) #-------------------------对应分组的群号---------------------------------- screenwidth = root.winfo_screenwidth() # 屏幕宽度 screenheight = root.winfo_screenheight() # 屏幕⾼度 width = 1000 height = 500 x = int((screenwidth - width) / 2) y = int((screenheight - height) / 2) root.geometry('{}x{}+{}+{}'.format(width, height, x, y)) # ⼤⼩以及位置 xscroll = Scrollbar(root, orient=HORIZONTAL) yscroll = Scrollbar(root, orient=VERTICAL) columns = ['序号', 'qq昵称', 'qq群昵称', 'qq号码', '性别', 'Q龄', '入群时间', '最近发言时间','手机号','地区','lol','微博UID'] table = ttk.Treeview( master=root, # ⽗容器 height=20, # 表格显⽰的⾏数,height⾏ columns=columns, # 显⽰的列 show='headings', # 隐藏⾸列 xscrollcommand=xscroll.set, # x轴滚动条 yscrollcommand=yscroll.set, # y轴滚动条 ) xscroll.config(command=table.xview) xscroll.pack(side=BOTTOM, fill=X) yscroll.config(command=table.yview) yscroll.pack(side=RIGHT, fill=Y) table.pack(fill=BOTH, expand=True) table.heading(column='序号', text='序号', anchor='w', command=lambda: print('序号')) # 定义表头 table.heading('qq昵称', text='qq昵称', ) # 定义表头 table.heading('qq群昵称', text='qq群昵称', ) # 定义表头 table.heading('qq号码', text='qq号码', ) # 定义表头 table.heading('性别', text='性别', ) # 定义表头 table.heading('Q龄', text='Q龄', ) # 定义表头 table.heading('入群时间', text='入群时间', ) # 定义表头 table.heading('最近发言时间', text='最近发言时间', ) # 定义表头 table.heading('手机号', text='手机号', ) # 定义表头 table.heading('地区', text='地区', ) # 定义表头 table.heading('lol', text='lol', ) # 定义表头 table.heading('微博UID', text='微博UID', ) # 定义表头 table.column('序号', width=50, minwidth=50, anchor=S, ) # 定义列 table.column('qq昵称', width=100, minwidth=100, anchor=S) # 定义列 table.column('qq群昵称', width=100, minwidth=100, anchor=S) # 定义列 table.column('qq号码', width=100, minwidth=100, anchor=S) # 定义列 table.column('性别', width=50, minwidth=50, anchor=S) # 定义列 table.column('Q龄', width=50, minwidth=50, anchor=S) # 定义列 table.column('入群时间', width=150, minwidth=150, anchor=S) # 定义列 table.column('最近发言时间', width=150, minwidth=150, anchor=S) # 定义列 table.column('手机号', width=100, minwidth=100, anchor=S) # 定义列 table.column('地区', width=100, minwidth=100, anchor=S) # 定义列 table.column('lol', width=100, minwidth=100, anchor=S) # 定义列 table.column('微博UID', width=100, minwidth=100, anchor=S) # 定义列 table.place(x = 10,y = 50) #添加一个命令输出框 log scroll=scrolledtext.ScrolledText(root,width=164,height=14,font=('黑体',10)) def Scroll(root): scroll.place(x=10,y=480) Scroll(root) #----------------------------操作数据------------------------------ #添加一个复选框 select_var = IntVar() select = Checkbutton(root, text='查询后四位数据(耗时)', variable=select_var) select.place(x = 520, y = 10) def chaxun(): #清空Scroll中的全部内容 scroll.delete(1.0,END) #清除table中的数据 table.delete(*table.get_children()) #设置查询的线程 threading.Thread(target=get_qq_member_list).start() #添加一个btn1按钮 btn1 = tk.Button(root,text = '查询',command = chaxun) btn1.config(font = ('微软雅黑',9)) btn1.config(width = 8) btn1.place(x = 680,y = 10) def save(): export_excel(qq_qun_info) messagebox.showinfo('提示','保存成功') save_path ='' def FileSave(): global save_path save_path = tkinter.filedialog.asksaveasfilename(title='保存',initialfile=value.get(),filetypes=[('excel', '*.xlsx')]) #如果用户点击了保存按钮则返回保存的文件名 if save_path: save() else: messagebox.showinfo('提示','取消保存') #添加一个btn2按钮 btn2 = tk.Button(root,text = '保存表格',command = FileSave) btn2.config(font = ('微软雅黑',9)) btn2.config(width = 8) btn2.place(x = 770,y = 10) #----------------------------操作数据------------------------------ #----------------------------界面---------------------------------- if __name__ == '__main__': #---------------只调试界面请注释本段代码---------------- global state qrsig = QR() ptqrtoken = ptqrtoken(qrsig) cookie = cookies(qrsig,ptqrtoken) skey = cookie[1] bkn = bkn(skey) ck = cookie[0] state = qun(ck, bkn,'434252251')#获取的cookie #---------------只调试界面请注释本段代码---------------- root.iconbitmap('imgs/favicon.ico') root.geometry('1190x700') root.title("QQ群信息爬取") root.resizable(False, False) root.mainloop()
分享到此结束。文章源自黄强博客-https://huangqiang.me/356.html

评论