精华内容
下载资源
问答
  • 好友管理系统

    千次阅读 2021-03-14 02:05:38
    好友管理系统 整体代码如下: import time import os import sys def tips(): print('*' * 5 + '欢迎使用好友管理系统' + '*' * 5) print('1、添加好友') print('2、删除好友') print('3、备注好友') print('...

    好友管理系统

    整体代码如下:

    import time
    import os
    import sys
    
    
    def tips():
        print('*' * 5 + '欢迎使用好友管理系统' + '*' * 5)
        print('1、添加好友')
        print('2、删除好友')
        print('3、备注好友')
        print('4、展示好友')
        print('5、退出')
    
    
    def addFriends():
        while True:
            name = input('请输入要添加的好友的姓名:')
            namelist.append(name)
            print(namelist)
            print('添加好友成功!!!恭喜恭喜!!!')
            quit1 = input('是否继续,按任意键继续,退出按q:')
            if quit1 != 'q':
                continue
            else:
                print('即将退出功能1.....')
                time.sleep(2)
                print('退出成功!')
            return
    
    
    def delFriends():
        if namelist != []:
            while True:
                friends = input('请输入一个要删除的好友姓名:')
                if friends in namelist:
                    namelist.remove(friends)
                    print('删除成功!!!恭喜恭喜!!!')
                    print(namelist)
                    quit2 = input('是否继续,按任意键继续,退出按q:')
                    if quit2 != 'q':
                        continue
                    else:
                        print('即将退出功能2......')
                        time.sleep(2)
                        print('退出成功!!!')
                    break
                else:
                    if namelist != []:
                        print('该好友不存在请重新输入!!!')
                        tips3 = input('按任意键继续删除好友,按q退出删除好友功能:')
                        if tips3 != 'q':
                            print('即将继续.....')
                        else:
                            print('即将退出功能2......')
                            time.sleep(2)
                            print('退出成功!!!')
                            break
                    else:
                        print('你的好友列表被清空了,快去功能1添加好友吧!!!')
                        time.sleep(3)
                        break
                continue
        else:
            print('你的好友列表中还没有好友哦,快进入功能1去添加一些吧!!!')
            time.sleep(3)
    
    
    def noteFriends():
        if namelist != []:
            while True:
                oldName = input('请输入要修改的好友姓名:')
                newName = input('请输入修改后的好友姓名:')
                if oldName in namelist:
                    index = namelist.index(oldName)
                    namelist[index] = newName
                    print('备注成功!!!恭喜恭喜!!!')
                    print(namelist)
                    tips4 = input('按任意键继续修改好友备注,按q退出修改备注功能:')
                    if tips4 == 'q':
                        print('即将退出功能3......')
                        time.sleep(2)
                        print('退出成功!!!')
                        break
                    else:
                        print('即将继续.....')
                else:
                    print('该好友不在你的好友名单中哦!!!')
                    print('备注失败!!!')
                    tips5 = input('按任意键继续修改好友备注,按q退出修改备注功能:')
                    if tips5 == 'q':
                        print('即将退出功能3......')
                        time.sleep(2)
                        print('退出成功!!!')
                        break
                    else:
                        print('即将继续!!!')
                continue
        else:
            print('你的好友列表中还没有好友哦,快进入功能1去添加一些吧!!!')
            time.sleep(3)
    
    
    def showFriends():
        if namelist != []:
            print('你的好友列表中有如下好友:{}'.format(namelist))
            time.sleep(3)
        else:
            print('你的好友列表为空!!!')
            time.sleep(3)
    
    
    def Exit():
        print('即将退出....')
        time.sleep(2)
        print('退出成功!!!')
        sys.exit()
    
    
    if __name__ == '__main__':
        namelist = []
        while True:
            tips()
            tips1 = input('请输入你想实现的功能所对应的序号:')
            if tips1 == str(1):
                addFriends()
                os.system('cls')
                continue
            elif tips1 == str(2):
                delFriends()
                os.system('cls')
                continue
            elif tips1 == str(3):
                noteFriends()
                os.system('cls')
                continue
            elif tips1 == str(4):
                showFriends()
                os.system('cls')
                continue
            elif tips1 == str(5):
                Exit()
    
    

    具体分析:

    第一步:制作主菜单页

    def tips():
        print('*' * 5 + '欢迎使用好友管理系统' + '*' * 5)
        print('1、添加好友')
        print('2、删除好友')
        print('3、备注好友')
        print('4、展示好友')
        print('5、退出')
    

    主要是一些输出语句没什么好说的

    第二步:实现功能1添加好友

    def addFriends():
        while True:
            name = input('请输入要添加的好友的姓名:')
            namelist.append(name)
            print(namelist)
            print('添加好友成功!!!恭喜恭喜!!!')
            quit1 = input('是否继续,按任意键继续,退出按q:')
            if quit1 != 'q':
                continue
            else:
                print('即将退出功能1.....')
                time.sleep(2)
                print('退出成功!')
            return
    

    说一些细节的东西,退出程序用return

    第三步:实现功能2删除好友

    def delFriends():
        if namelist != []:
            while True:
                friends = input('请输入一个要删除的好友姓名:')
                if friends in namelist:
                    namelist.remove(friends)
                    print('删除成功!!!恭喜恭喜!!!')
                    print(namelist)
                    quit2 = input('是否继续,按任意键继续,退出按q:')
                    if quit2 != 'q':
                        continue
                    else:
                        print('即将退出功能2......')
                        time.sleep(2)
                        print('退出成功!!!')
                    break
                else:
                    if namelist != []:
                        print('该好友不存在请重新输入!!!')
                        tips3 = input('按任意键继续删除好友,按q退出删除好友功能:')
                        if tips3 != 'q':
                            print('即将继续.....')
                        else:
                            print('即将退出功能2......')
                            time.sleep(2)
                            print('退出成功!!!')
                            break
                    else:
                        print('你的好友列表被清空了,快去功能1添加好友吧!!!')
                        time.sleep(3)
                        break
                continue
        else:
            print('你的好友列表中还没有好友哦,快进入功能1去添加一些吧!!!')
            time.sleep(3)
    

    在这里我遇到两个问题,一个是数据类型不正确,namelist本来是列表类型,结果我用了字符串与他进行比较,二是break和continue的区别,break是用于跳出for循环和while循环的,而continue是跳出本次循环进入下一次,这里虽然简单但是也容易出错,我错就错在以为if 和else也需要使用break跳出,其实if 和else如果后面没有continue是会自己跳出的,并不需要使用break。

    第四步:实现功能3备注好友

    def noteFriends():
        if namelist != []:
            while True:
                oldName = input('请输入要修改的好友姓名:')
                newName = input('请输入修改后的好友姓名:')
                if oldName in namelist:
                    index = namelist.index(oldName)
                    namelist[index] = newName
                    print('备注成功!!!恭喜恭喜!!!')
                    print(namelist)
                    tips4 = input('按任意键继续修改好友备注,按q退出修改备注功能:')
                    if tips4 == 'q':
                        print('即将退出功能3......')
                        time.sleep(2)
                        print('退出成功!!!')
                        break
                    else:
                        print('即将继续.....')
                else:
                    print('该好友不在你的好友名单中哦!!!')
                    print('备注失败!!!')
                    tips5 = input('按任意键继续修改好友备注,按q退出修改备注功能:')
                    if tips5 == 'q':
                        print('即将退出功能3......')
                        time.sleep(2)
                        print('退出成功!!!')
                        break
                    else:
                        print('即将继续!!!')
                continue
        else:
            print('你的好友列表中还没有好友哦,快进入功能1去添加一些吧!!!')
            time.sleep(3)b
    

    备注好友需要考虑好友列表为空的情况,包括上面的删除好友也是

    第五步:实现功能4展示好友

    def showFriends():
        if namelist != []:
            print('你的好友列表中有如下好友:{}'.format(namelist))
            time.sleep(3)
        else:
            print('你的好友列表为空!!!')
            time.sleep(3)
    

    第六步:实现功能5退出程序

    def Exit():
        print('即将退出....')
        time.sleep(2)
        print('退出成功!!!')
        sys.exit()
    

    第七步:调用函数,测试代码

    if __name__ == '__main__':
        namelist = []
        while True:
            tips()
            tips1 = input('请输入你想实现的功能所对应的序号:')
            if tips1 == str(1):
                addFriends()
                os.system('cls')
                continue
            elif tips1 == str(2):
                delFriends()
                os.system('cls')
                continue
            elif tips1 == str(3):
                noteFriends()
                os.system('cls')
                continue
            elif tips1 == str(4):
                showFriends()
                os.system('cls')
                continue
            elif tips1 == str(5):
                Exit()
    

    这一部分是函数的入口,调用了上面的功能函数,使用了os.system()方法进行清屏,使用了exit()方法退出程序。

    展开全文
  • 其分析结果如下图所示: 可以注意到,在所有微信好友中,约有接近1/4的微信好友使用了人脸头像, 而有接近3/4的微信好友没有人脸头像,这说明在所有微信好友中对”颜值 “有自信的人,仅仅占到好友总数的25%,或者说...


    最近微信迎来了一次重要的更新,允许用户对”发现”页面进行定制。不知道从什么时候开始,微信朋友圈变得越来越复杂,当越来越多的人选择”仅展示最近三天的朋友圈”,大概连微信官方都是一脸的无可奈何。逐步泛化的好友关系,让微信从熟人社交逐渐过渡到陌生人社交,而朋友圈里亦真亦幻的状态更新,仿佛在努力证明每一个个体的”有趣”。

    有人选择在朋友圈里记录生活的点滴,有人选择在朋友圈里展示观点的异同,可归根到底,人们无时无刻不在窥探着别人的生活,唯独怕别人过多地了解自己的生活。人性中交织着的光明与黑暗,像一只浑身长满刺的刺猬,离得太远会感觉到寒冷,而靠得太近则害怕被刺扎到。朋友圈就像过年走亲戚,即便你心中有一万个不痛快,总是不愿意撕破脸,或屏蔽对方,或不给对方看,或仅展示最后三天,于是通讯录里的联系人越来越多,朋友圈越来越大,可再不会有能真正触动你内心的”小红点”出现,人类让一个产品变得越来越复杂,然后说它无法满足人类的需求,这大概是一开始就始料不及的吧!

    引言

    有人说,人性远比计算机编程更复杂,因为即使是人类迄今为止最伟大的发明——计算机,在面对人类的自然语言时同样会张惶失措 。人类有多少语言存在着模棱两可的含义,我认为语言是人类最大的误解,人类时常喜欢揣测语言背后隐藏的含义,好像在沟通时表达清晰的含义会让人类没有面子,更不用说网络上流行的猜测女朋友真实意图的案例。金庸先生的武侠小说《射雕英雄传》里,在信息闭塞的南宋时期,江湖上裘千丈的一句鬼话,就搅得整个武林天翻地覆。其实,一两句话说清楚不好吗?黄药师、全真七子、江南六怪间的种种纠葛,哪一场不是误会?一众儿武功震古烁今的武林高手,怎么没有丝毫的去伪存真的能力,语言造成了多少误会。

    可即便人类的语言复杂得像一本无字天书,可人类还是从这些语言中寻觅到蛛丝马迹。古人有文王”拘而演周易”、东方朔测字卜卦,这种带有”迷信”色彩的原始崇拜,就如同今天人们迷信星座运势一般,都是人类在上千年的演变中不断对经验进行总结和训练的结果。如此说起来,我们的人工智能未尝不是一种更加科学化的”迷信”,因为数据和算法让我们在不断地相信,这一切都是真实地。生活在数字时代的我们,无疑是悲哀的,一面努力地在别人面前隐藏真实地自己,一面不无遗憾地感慨自己无处遁逃,每一根数字神经都紧紧地联系着你和我,你不能渴望任何一部数字设备具备真正的智能,可你生命里的每个瞬间,都在悄然间被数据地折射出来。

    今天这篇文章会基于 Python 对微信好友进行数据分析,这里选择的维度主要有:性别、头像、签名、位置,主要采用图表和词云两种形式来呈现结果,其中,对文本类信息会采用词频分析和情感分析两种方法。常言道:工欲善其事,必先利其器也。在正式开始这篇文章前,简单介绍下本文中使用到的第三方模块:

    • itchat:微信网页版接口封装Python版本,在本文中用以获取微信好友信息。

    • jieba:结巴分词的 Python 版本,在本文中用以对文本信息进行分词处理。

    • matplotlib: Python 中图表绘制模块,在本文中用以绘制柱形图和饼图

    • snownlp:一个 Python 中的中文分词模块,在本文中用以对文本信息进行情感判断。

    • PIL: Python 中的图像处理模块,在本文中用以对图片进行处理。

    • numpy: Python中 的数值计算模块,在本文中配合 wordcloud 模块使用。

    • wordcloud: Python 中的词云模块,在本文中用以绘制词云图片。

    • TencentYoutuyun:腾讯优图提供的 Python 版本 SDK ,在本文中用以识别人脸及提取图片标签信息。

    以上模块均可通过 pip 安装,关于各个模块使用的详细说明,请自行查阅各自文档。

    数据分析

    分析微信好友数据的前提是获得好友信息,通过使用 itchat 这个模块,这一切会变得非常简单,我们通过下面两行代码就可以实现:

    itchat.auto_login(hotReload = True)
    
    friends = itchat.get_friends(update = True)
    

    同平时登录网页版微信一样,我们使用手机扫描二维码就可以登录,这里返回的friends对象是一个集合,第一个元素是当前用户。所以,在下面的数据分析流程中,我们始终取friends[1:]作为原始输入数据,集合中的每一个元素都是一个字典结构,以我本人为例,可以注意到这里有Sex、City、Province、HeadImgUrl、Signature这四个字段,我们下面的分析就从这四个字段入手:

    好友性别

    分析好友性别,我们首先要获得所有好友的性别信息,这里我们将每一个好友信息的Sex字段提取出来,然后分别统计出Male、Female和Unkonw的数目,我们将这三个数值组装到一个列表中,即可使用matplotlib模块绘制出饼图来,其代码实现如下:在这里插入图片描述
    这里简单解释下这段代码,微信中性别字段的取值有Unkonw、Male和Female三种,其对应的数值分别为0、1、2。通过Collection模块中的Counter()对这三种不同的取值进行统计,其items()方法返回的是一个元组的集合,该元组的第一维元素表示键,即0、1、2,该元组的第二维元素表示数目,且该元组的集合是排序过的,即其键按照0、1、2 的顺序排列,所以通过map()方法就可以得到这三种不同取值的数目,我们将其传递给matplotlib绘制即可,这三种不同取值各自所占的百分比由matplotlib计算得出。下图是matplotlib绘制的好友性别分布图:

    看到这个结果,我一点都不觉得意外,男女比例严重失衡,这虽然可以解释我单身的原因,可我不觉得通过调整男女比例就能解决问题,好多人认为自己单身是因为社交圈子狭小,那么是不是扩展了社交圈子就能摆脱单身呢?我觉得或许这样会增加脱单的概率,可幸运之神应该不会眷顾我,因为我的好运气早在我24岁以前就消耗完啦。在知乎上有一个热门的话题:现在的男性是否普遍不再对女性展开追求了?,其实哪里会有人喜欢孤独呢?无非是怕一次又一次的失望罢了。有的人并不是我的花儿,我只是恰好途径了她的绽放。曾经有人说我是一个多情的人,可她永远不会知道,我做出的每一个决定都炽热而悲壮。所谓”慧极必伤,情深不寿;谦谦君子,温润如玉”,世人苦五毒者大抵如此。

    好友头像

    分析好友头像,从两个方面来分析,第一,在这些好友头像中,使用人脸头像的好友比重有多大;第二,从这些好友头像中,可以提取出哪些有价值的关键字。这里需要根据HeadImgUrl字段下载头像到本地,然后通过腾讯优图提供的人脸识别相关的API接口,检测头像图片中是否存在人脸以及提取图片中的标签。其中,前者是分类汇总,我们使用饼图来呈现结果;后者是对文本进行分析,我们使用词云来呈现结果。关键代码如下 所示:
    在这里插入图片描述
    这里我们会在当前目录新建一个HeadImages目录,用以存储所有好友的头像,然后我们这里会用到一个名为FaceApi类,这个类由腾讯优图的SDK封装而来,这里分别调用了人脸检测和图像标签识别两个API接口,前者会统计”使用人脸头像”和”不使用人脸头像”的好友各自的数目,后者会累加每个头像中提取出来的标签。其分析结果如下图所示:

    可以注意到,在所有微信好友中,约有接近1/4的微信好友使用了人脸头像, 而有接近3/4的微信好友没有人脸头像,这说明在所有微信好友中对”颜值 “有自信的人,仅仅占到好友总数的25%,或者说75%的微信好友行事风格偏低调为主,不喜欢用人脸头像做微信头像。这是否说明”好看的皮囊”并非是千篇一律,长得好看的人实在是少数中的少数。所以,当女生的妆容越来越向着”韩式半永久粗平眉”、”瓜子脸”和”大红唇”靠拢的时候,当男生的服饰越来越向着”大背头”、”高领毛衣”和”长款大衣”靠拢的时候,我们能不能真正得个性一次。生命中有太多被世俗绑架着的事情,既要和别人不一样 ,同时还要和大多数人一样,这是人生在世的无可奈何。考虑到腾讯优图并不能真正得识别”人脸”,我们这里对好友头像中的标签再次进行提取,来帮助我们了解微信好友的头像中有哪些 关键词,其分析结果如图所示:

    通过词云,我们可以发现:在微信好友中的签名词云中,出现频率相对较高的关键字有:女孩、树木、房屋、文本、截图、卡通、合影、天空、大海。这说明在我的微信好友中,好友选择的微信头像主要有日常、旅游、风景、截图四个来源,好友选择的微信头像中风格以卡通为主,好友选择的微信头像中常见的要素有天空、大海、房屋、树木。通过观察所有好友头像,我发现在我的微信好友中,使用个人照片作为微信头像的有15人,使用网络图片作为微信头像的有53人,使用动漫图片作为微信头像的有25人,使用合照图片作为微信头像的有3人,使用孩童照片作为微信头像的有5人,使用风景图片作为微信头像的有13人,使用女孩照片作为微信头像的有18人,基本符合图像标签提取的分析结果。

    好友签名

    分析好友签名,签名是好友信息中最为丰富的文本信息,按照人类惯用的”贴标签”的方法论,签名可以分析出某一个人在某一段时间里状态,就像人开心了会笑、哀伤了会哭,哭和笑两种标签,分别表明了人开心和哀伤的状态。这里我们对签名做两种处理,第一种是使用用结巴分词进行分词后生成词云,目的是了解好友签名中的关键字有哪些,哪一个关键字出现的频率相对较高;第二种是使用SnowNLP分析好友签名中的感情倾向,即好友签名整体上是表现为正面的、负面的还是中立的,各自的比重是多少。这里提取Signature字段即可,其核心代码如下:

    通过词云,我们可以发现:在微信好友的签名信息中,出现频率相对较高的关键词有:努力、长大、美好、快乐、生活、幸福、人生、远方、时光、散步。果然我的微信好友都是温暖、正直的好青年啊! 😄其实,签名这个设定,从某种程度上是在反映人的一种心态,人在年轻时不免”为赋新词强说愁”,等到你真正到了这个精神境界,突然发现年轻时图样图森破,或许这就是我们不愿意让别人了解过去的原因,因为伴随着人的成长,某一种瞬间的状态简直不忍直视,QQ空间陪伴了我们这代人的整个青春,令人印象深刻的”那年今日”功能,有时让我们感到回忆的温暖,有时让我们感到岁月的萧杀,”当时只道是寻常”的物是人非,”回首向来萧瑟处”的淡定从容,”今夕复何夕”的失落惆怅……都在这一行行签名里留下深深浅浅的印记。在知乎上有关于签名的话题讨论,对此感兴趣的朋友不妨找时间看看。

    通过柱状图,我们可以发现:在微信好友的签名信息中,正面积极的情感判断约占到55.56%,中立的情感判断约占到32.10%,负面消极的情感判断约占到12.35%。这个结果和我们通过词云展示的结果基本吻合,这说明在微信好友的签名信息中,约有87.66%的签名信息,传达出来都是一种积极向上的态度。

    朋友圈中基本上有两类用户,第一类用户使用朋友圈记录自己的生活,第二类用户使用朋友圈输出自己的观点。显然,对于第二类用户,它并不介意别人了解它的过去,它更在乎它从始至终输出的观点是否一致。所以,不管朋友圈里别人在或晒美食、或晒旅游、或秀恩爱、或晒宝宝、或煲鸡汤等等,在我看来这都是一种生活方式,精神层次和物质层次比你高的人群,觉得你朋友圈里的内容”无趣”,这是符合人类一贯的认知方式的。

    在大多数情况下,反而是那些和你层次差不多的人群,对不熟悉的人或者事物妄加判断,如果你不喜欢我朋友圈里的内容,请直接屏蔽我就好,因为这样我们还可以做朋友;如果你因为喜欢A而在我这里和我说B不好,这就真的是三观不合啦。我相信没有完全兴趣匹配的两个人,即使是男女朋友或者情侣之间,总之人与人相处嘛,真诚和互相尊重是基本要求。

    好友位置

    分析好友位置,主要通过提取Province和City这两个字段。Python中的地图可视化主要通过Basemap模块,这个模块需要从国外网站下载地图信息,使用起来非常的不便。百度的ECharts在前端使用的比较多,虽然社区里提供了pyecharts项目,可我注意到因为政策的改变,目前Echarts不再支持导出地图的功能,所以地图的定制方面目前依然是一个问题,主流的技术方案是配置全国各省市的JSON数据,这里博主使用的是BDP个人版,这是一个零编程的方案,我们通过Python导出一个CSV文件,然后将其上传到BDP中,通过简单拖拽就可以制作可视化地图,简直不能再简单,这里我们仅仅展示生成CSV部分的代码:

    在这里插入图片描述
    下图是BDP中生成的微信好友地理分布图,可以发现:我的微信好友主要集中在宁夏和陕西两个省份。数字时代的神经牵动着每一个社交关系链的人,我们想要竭力去保护的那点隐私,在这些数据中一点点地折射出来。人类或许可以不断地伪装自己,可这些从数据背后抽离出来的规律和联系不会欺骗人类。数学曾经被人称为最没有用的学科,因为生活中并不需要神圣而纯粹的计算,在不同的学科知识里,经验公式永远比理论公式更为常用。可是此时此刻,你看,这世界就像一只滴滴答答转动着的时钟,每一分每一秒都是严丝合缝的。

    本文小结

    写这篇文章的时候,我一直不知道该如何下笔,因为微信是一个神奇的存在,它是一个国民级别的全民APP,所以,微信的产品设计一直都是一个有趣的现象,从最初底部Tab的数目、每个Tab的名称、”发现”页面的定制、小程序入口、朋友圈入口到朋友圈评论等等一系列的设计细节,都是值得我们透过人性和心理去研究的。即使是被人们封神的”张小龙”,在面对结构最为复杂的中国用户群体的时候,他的潇洒中依旧不免充满无奈,从对朋友圈的置之不理就可以看出,这是一个怎么做都不会让人满意的功能,任何一个生态在面对巨大的用户群体的时候,功能的增减就会变成一个难题,所谓”林子大了什么鸟都有”,知乎面对的是同样的问题,营销类公众号在不断消费社会话题的同时,引导着一批又一批粉丝的价值取向,人类总渴望着别人了解自己,可人类真的了解自己吗?这篇博客是我对数据分析的又一次尝试,主要从性别、头像、签名、位置四个维度,对微信好友进行了一次简单的数据分析,主要采用图表和词云两种形式来呈现结果。总而言之一句话,”数据可视化是手段而并非目的”,重要的不是我们在这里做了这些图出来,而是从这些图里反映出来的现象,我们能够得到什么本质上的启示,我一位朋友问我怎么什么都想抓取,为什么啊,因为我不懂人类啊!


    关注公众号:程序员二黑,分享软件测试资源(面试题、PDF文档、视频教程)

    好东西要跟朋友一起分享哦

    展开全文
  • 简介加好友,大家用过QQ都知道,无非是发起好友申请,对方收到消息通知,然后处理。不过,本篇只讲前半部分,消息通知的处理留到下一篇去讲。因为内容有点多,怕是一时半会消化不了。在介绍主体流程之前,先给大家介...

    前言

    在上一篇 Spring boot + LayIM + t-io 文件上传、 监听用户状态的实现 中,已经介绍了两个小细节:用户的在离线状态和群人数的状态变化。今天的主要内容就是用户加好友的实现。

    简介

    加好友,大家用过QQ都知道,无非是发起好友申请,对方收到消息通知,然后处理。不过,本篇只讲前半部分,消息通知的处理留到下一篇去讲。因为内容有点多,怕是一时半会消化不了。在介绍主体流程之前,先给大家介绍一下准备工作。

    准备工作

    首先,为了让数据更贴近实战,所以我用了比较“真实”的用户数据。结合fly模板,完善了用户中心头部的用户信息的数据绑定。数据绑定部分判断了是否已经是好友,来决定是否出现“加为好友”的按钮。示例如下,当用户自己看到自己的主页时,是这样的:

    b499f37d1f7447d92d901f650901dc10.png

    看到非好友的用户主页,是这样的:

    79b6f5b6404a30d7f726c68b81294019.png

    绑定数据部分,简单给大家介绍一下,就是用thymleaf模板绑定。后台访问页面的时候,将 Model 赋值即可。

    /**

    * 属性赋值

    * */

    private void setModel(User user,Model model){

    long currentUserId = getUserId();

    long visitUserId = user.getId();

    //是否是自己

    boolean isSelf = currentUserId == visitUserId;

    //两个用户是否已经是好友

    boolean isFriend = groupService.isFriend(currentUserId,visitUserId);

    Map userMap = new HashMap<>(8);

    userMap.put("avatar",user.getAvatar());

    userMap.put("name",user.getUserName());

    userMap.put("addtime", TimeUtil.formatDate(user.getCreateAt())+" 加入");

    if(user.getSign()==null ||user.getSign().length()==0) {

    userMap.put("sign", "");

    }else {

    userMap.put("sign", "(" + user.getSign() + ")");

    }

    userMap.put("uid",user.getId());

    userMap.put("self",isSelf || isFriend);

    model.addAttribute("user",userMap);

    }

    然后页面上,将model中的数据取出来。

    ok,以上就是简单的准备工作。想了解详情代码的可以去文末的github地址去搜寻。

    发起好友申请

    我们先根据layim的业务分析。首先,要知道我们要加谁(toId)为好友。然后在加上一个备注(remark)。这些东西交给后台就OK了。为了避免连表查询,对于系统消息的存储我做了用户名和用户头像的冗余。表主要包含字段:用户ID,用户头像,用户名,被申请用户ID,申请时间,申请类型,备注,已读等其他属性。

    所以,发起好友申请就很简单了。就是一个添加功能,前端传的就是被申请人用户ID和申请备注,后端组织数据插入到数据库,代码如下:

    /**

    * 提交好友申请

    * */

    public JsonResult saveFriendApply(long toId,String remark){

    remark = HtmlUtils.htmlEscape(remark);

    ContextUser user = ShiroUtil.getCurrentUser();

    long userId = Long.parseLong(user.getUserid());

    int record = applyRepository.countByToidAndUidAndTypeAndResult(toId,userId,ApplyType.friend,0);

    if(record > 0){

    return JsonResult.fail("已经申请过");

    }

    Apply apply = new Apply();

    apply.setType(ApplyType.friend);

    apply.setToid(toId);

    apply.setRemark(remark);

    apply.setUid(userId);

    apply.setAvatar(user.getAvatar());

    apply.setName(user.getUsername());

    apply.setRead(false);

    apply.setResult(0);

    return saveApply(apply);

    }

    OK,申请完了,下面我们要做啥?没错,通知对方,喂,我向你发送了申请,快快处理。在这里呢我遇到了一个问题。由于springboot程序占用端口 8080,而t-io占用端口8888,也就是说,如果我想在8080端口的业务中主动调用8888的服务推送,我不知道如何获取相应的channelContext。不过经过询问作者之后,一句话解决了我的问题。

    拿到 ServerGroupContext ,问题迎刃而解。

    在之前的程序启动的时候注册了 LayimWebsocketStarter 这个bean。所以,在8080业务端如果能拿到它的话就没问题了。

    得到 LayimWebsocketStarter ,就能得到  ServerGroupContext, 然后就能在服务端做主动推送了。

    当然可能没有开发过这个东西,对于上文中的问题不是很理解,没关系,其实我就想说明,如果从服务端主动向客户端推送消息的话,使用ServerGroupContext即可。

    服务端主动推送

    以下代码在  com.fyp.layim.im.common.util.PushUtil 中

    OK,接上文,我们按照步骤来。

    第一步,获取 LayimWebsocketStarter 。

    /**

    * 获取starter

    */

    private static LayimWebsocketStarter getStarter(){

    return (LayimWebsocketStarter)SpringUtil.getBean("layimWebsocketStarter");

    }

    第二步,获取 ServerGroupContext

    private static ServerGroupContext getServerGroupContext(){

    return getStarter().getServerGroupContext();

    }

    第三步,获取 ChannelContext。

    /**

    * 获取channelContext

    * */

    private static ChannelContext getChannelContext(String toId) {

    ServerGroupContext context = getServerGroupContext();

    //找到用户

    ChannelContext channelContext = context.users.find(context, toId);

    return channelContext;

    }

    第四步,发射,这里的代码就和聊天中的那部分代码差不多了。核心部分就是,获取ChannelContext,然后给他发送消息。如果不在线就不用管。

    /**

    * 服务端主动推送消息

    * */

    public static void pushApplyMessage(String toId) {

    logger.info("执行到了发送方法:pushApplyMessage");

    LayimToClientNoticeMsgBody body = new LayimToClientNoticeMsgBody();

    ChannelContext channelContext = getChannelContext(toId);

    //先判断是否在线,再去查询数据库,减少查询次数

    if (channelContext != null && !channelContext.isClosed()) {

    int count = getApplyService().getUnreadMsgCount(Long.parseLong(toId));

    body.setCount(count);

    push(channelContext, body);

    }

    }

    /**

    * 服务端主动推送消息

    * */

    private static void push(ChannelContext channelContext,Object msg) {

    try {

    WsResponse response = BodyConvert.getInstance().convertToTextResponse(msg);

    Aio.send(channelContext, response);

    }catch (IOException ex){

    }

    }

    现在推送已经搞定了,那么什么时候推送呢?由于这个系统消息的推送可以不用那么即时,于是我看了下,springboot里面有类似的事件机制,于是乎 ApplyEvent 就诞生了。

    public class ApplyEvent extends ApplicationEvent {

    public ApplyEvent(Object source) {

    super(source);

    }

    private long toid;

    public long getToId(){

    return toid;

    }

    public ApplyEvent(Object source, long toId) {

    super(source);

    this.toid = toId;

    }

    }

    在创建一个Listener,监听事件。

    public class ApplyListener implements ApplicationListener {

    private Logger logger = LoggerFactory.getLogger(ApplyListener.class);

    @Override

    public void onApplicationEvent(ApplyEvent applyEvent) {

    new Thread(){

    public void run(){

    Long toId = applyEvent.getToId();

    //这里就要调用上文中的推送了

    PushUtil.pushApplyMessage(toId.toString());

    }

    }.start();

    }

    }

    不过我有个疑问,发现listener中执行的时候是同步的。后来加了@Async 和@EnableAsync 也没用,于是我就用了new Thread().start()实现异步,确保不影响主要申请流程。(这是个疑问,自己没搞明白的地方)

    最后,别忘了在Application启动的时候把listener加上。

    public static void main(String[] args) {

    SpringApplication springApplication = new SpringApplication(LayimApplication.class);

    /**

    * 这里监听增加listener,listener才会触发

    * ApplyListener 是监听好友申请的事件

    * */

    springApplication.addListeners(new ApplyListener());

    springApplication.run(args);

    }

    功能拼接

    马上就要成功了,我们在把事件串起来,在好友申请成功之后,发布事件。

    /**

    * 好友申请

    * */

    @PostMapping(value = "/apply-friend")

    public JsonResult apply(@RequestParam("toid") Long toId,@RequestParam("remark") String remark){

    JsonResult result = applyService.saveFriendApply(toId, remark);

    //申请成功,发布申请事件,通知 toId处理消息,如果不在线,不会进行处理

    if(result.isSuccess()){

    applicationContext.publishEvent(new ApplyEvent("apply",toId));

    }

    return result;

    }

    功能演示

    讲了那么多,给大家看一下成品效果。(用户场景:安小鸟加皇上为好友,皇上接收消息并查看)

    140f1a1cbdcacaba5a632b993ba545c3.png

    皇上收到消息,系统弹出左下角的小数字4。(调用 layim.msgbox(msgCount) 方法)

    267bc71224e66f632afcf4db14da5cf6.png

    皇上点开消息盒子:

    cab774a5964217d0aebbe8c25f67bfcd.png

    皇上收到了四位爱妃的申请,寝食难安,他会怎么处理呢?欲知后事如何,且听下回分解~~~

    总结

    本篇主要介绍了一个加好友的流程的实现。

    好友申请按钮出不出现取决于用户是否为自己,是否已经是好友。(后端也要做验证)

    t-io的服务端主动推送,如何调用。关键词: ServerGroupContext

    event的使用,除了applicationEvent,还可以拓展其他类型,如消息队列,eventbus等。

    各种细节处理,比如先判断对方是否在线,在去查询数据库。或者结合缓存等

    由于是自己摸索,难免有代码繁杂混乱之处,

    以上所述是小编给大家介绍的SpringBoot+LayIM+t-io 实现好友申请通知流程,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

    展开全文
  • 本帖最后由 hjw45611 于 2019-3-14 15:23 编辑严重声明本文的意图只有一个就是通过分析app学习更多的逆向...前两天有人想让我做一个微信自动加好友的功能,今天就想试一试。以微信6.6.7版本为例,手机root与Xposed...

    本帖最后由 hjw45611 于 2019-3-14 15:23 编辑

    严重声明

    本文的意图只有一个就是通过分析app学习更多的逆向技术,如果有人利用本文知识和技术进行非法操作进行牟利,带来的任何法律责任都将由操作者本人承担,和本文作者无任何关系,最终还是希望大家能够秉着学习的心态阅读此文。

    前两天有人想让我做一个微信自动加好友的功能,今天就想试一试。

    以微信6.6.7版本为例,手机root与Xposed框架安装本文不做讨论,如有需要查看论坛内其他帖子,本文只用于Xposed模块编写。

    thread-872046-1-1.html

    经坛友提醒,使用文本存储手机号,在进行读取for循环添加时,10个以上的时候就会产生操作过于频繁的提醒,而且这个提醒大概一个小时才能解除。

    经过优化后,增加了线程的sleep时间,可实现自动循环查看好友信息,但在运行到25个左右时也会触发操作过于频繁的提醒。

    并且如果加好友的功能也增加上的话,也会由于加好友频繁而被限制,所以最好是通过ContentProvider把大量手机号批量写入到手机通讯录数据库中,然后使用微信的添加通讯录好友的方式来添加好友,但有网友反应可用,也有网友反应加的多了收不到验证信息,我也并未实验, 以下分析流程就仅做参考吧。

    至今(2019-03-14)微信自动加好友的分析已经完成,主要分三步:

    1.查找好友(本文)

    2.自动点击添加好友按钮进入验证页面

    https://www.52pojie.cn/thread-886190-1-1.html

    3.自动发送验证信息

    https://www.52pojie.cn/thread-897346-1-1.html

    希望喜欢Xposed的朋友能交流学习,从中获益。

    1.首先查看微信加好友的页面

    是FTSAddFriendUI这个Activity。

    2.使用jadx打开app,查找FTSAddFriendUI

    3.寻找突破点

    55fd2b2273b5a8b4531f72773c469d6e.gif

    屏幕快照 2019-02-18 22.13.24.png (119.18 KB, 下载次数: 15)

    2019-2-19 09:31 上传

    大体浏览后没有类似EditView的实例对象,但发现一个内部类FTSAddFriendUI$5

    55fd2b2273b5a8b4531f72773c469d6e.gif

    屏幕快照 2019-02-18 17.49.34.png (307.29 KB, 下载次数: 9)

    2019-2-19 09:31 上传

    -1通过简单分析,确定这个内部类是搜索好友后的结果显示

    成功的话就intent跳转,失败的话就显示该用户不存在等错误信息

    -2直接查找它的使用

    是CM方法使用到它了,分析可得这个方法的参数就是输入框的字符串,字符串不为空后进行查询,并显示一个正在查询的Dialog,有结果后回调OnCancelListener,并且触发内部类FTSAddFriendUI$5中的结果显示方法。

    55fd2b2273b5a8b4531f72773c469d6e.gif

    屏幕快照 2019-02-18 17.52.33.png (144.55 KB, 下载次数: 8)

    2019-2-19 09:32 上传

    Hook CM方法,打印string参数,发现就是输入框的文本数据,确认CM方法就是要找的方法

    -3xposed直接使用

    [Java] 纯文本查看 复制代码final Class FTSAddFriendUIClass=loadPackageParam.classLoader.loadClass("com.tencent.mm.plugin.fts.ui.FTSAddFriendUI");

    findAndHookMethod(FTSAddFriendUIClass,

    "onCreate",Bundle.class,

    new XC_MethodHook() {

    @Override

    protected void afterHookedMethod(final MethodHookParam param) throws Throwable {

    super.afterHookedMethod(param);

    new Handler().postDelayed(new Runnable() {

    @Override

    public void run() {

    XposedHelpers.callMethod(param.thisObject,"CM","微信号/QQ号/手机号");

    }

    },1000);

    }

    });

    55fd2b2273b5a8b4531f72773c469d6e.gif

    searchUserErr.gif (709.39 KB, 下载次数: 8)

    2019-2-19 09:33 上传

    -4解决问题

    结果可以看到只有dialog,dialog结束后并没有反应,但dialog能显示说明代码执行了,那就来看一下FTSAddFriendUI$5这个结果处理类里的方法有没有执行吧。

    [Java] 纯文本查看 复制代码findAndHookMethod("com.tencent.mm.plugin.fts.ui.FTSAddFriendUI$5",loadPackageParam.classLoader,

    "a",int .class, int .class,String.class,XposedHelpers.findClass("com.tencent.mm.ab.l",loadPackageParam.classLoader) ,

    new XC_MethodHook() {

    @Override

    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

    super.beforeHookedMethod(param);

    log("FTSAddFriendUI$5--0="+param.args[0]+"=1="+param.args[1]+

    "=2="+param.args[2]);

    }

    });

    打印结果如下:

    2019-02-18 17:55:19.347 3872-3872/? I/Xposed: [17:55:19]:  FTSAddFriendUI$5--0=0=1=0=2=Everything is OK

    搜索结果处理的方法执行了,说明问题不在CM方法,而是在处理方法中因为某个问题而停止了。

    那就来分析一下这个a方法里的哪段代码是有问题的吧。a方法完整代码如下,

    [Java] 纯文本查看 复制代码public final void mo2331a(int i, int i2, String str, C0879l c0879l) {

    C1261g.m2963DF().mo8629b(106, (C0874e) this);

    FTSAddFriendUI.this.aQA();

    if (i == 0 && i2 == 0) {

    FTSAddFriendUI.this.iJw = ((C9339f) c0879l).bcS();

    if (FTSAddFriendUI.this.iJw.rHb > 0) {

    if (FTSAddFriendUI.this.iJw.rHc.isEmpty()) {

    C35785h.m67602a(FTSAddFriendUI.this, C8733g.search_contact_not_found, 0, true, null);

    return;

    }

    Intent intent = new Intent();

    intent.putExtra("add_more_friend_search_scene", 3);

    if (FTSAddFriendUI.this.iJw.rHc.size() > 1) {

    try {

    intent.putExtra("result", FTSAddFriendUI.this.iJw.toByteArray());

    C36379d.m70344b(FTSAddFriendUI.this.mController.tml, "subapp", ".ui.pluginapp.ContactSearchResultUI", intent);

    return;

    } catch (Throwable e) {

    C3327x.printErrStackTrace("MicroMsg.FTS.FTSAddFriendUI", e, "", new Object[0]);

    return;

    }

    }

    ((C33521h) C1261g.m2977l(C33521h.class)).mo24028a(intent, (biy) FTSAddFriendUI.this.iJw.rHc.getFirst(), FTSAddFriendUI.this.jvZ);

    }

    FTSAddFriendUI.this.jvX = 1;

    FTSAddFriendUI.m48692g(FTSAddFriendUI.this);

    } else {

    switch (i2) {

    case DownloadResult.CODE_CONNECTION_EXCEPTION /*-24*/:

    C29477a eV = C29477a.m50825eV(str);

    if (eV == null) {

    FTSAddFriendUI.this.jvQ.setText(C8733g.no_contact_result);

    break;

    } else {

    FTSAddFriendUI.this.jvQ.setText(eV.desc);

    break;

    }

    case -4:

    if (i != 4) {

    FTSAddFriendUI.this.jvQ.setText(FTSAddFriendUI.this.getString(C8733g.search_contact_err_no_code));

    break;

    }

    default:

    FTSAddFriendUI.this.jvQ.setText(C8733g.no_contact_result);

    break;

    }

    FTSAddFriendUI.this.jvX = -1;

    FTSAddFriendUI.this.jvY = 1;

    }

    FTSAddFriendUI.m48693h(FTSAddFriendUI.this);

    }

    因为上面打印log时前两个参数都是0,所以精简后如下

    [Java] 纯文本查看 复制代码public final void mo2331a(int i, int i2, String str, C0879l c0879l) {

    C1261g.m2963DF().mo8629b(106, (C0874e) this);

    FTSAddFriendUI.this.aQA();

    if (i == 0 && i2 == 0) {

    FTSAddFriendUI.this.iJw = ((C9339f) c0879l).bcS();

    if (FTSAddFriendUI.this.iJw.rHb > 0) {

    if (FTSAddFriendUI.this.iJw.rHc.isEmpty()) {

    C35785h.m67602a(FTSAddFriendUI.this, C8733g.search_contact_not_found, 0, true, null);

    return;

    }

    Intent intent = new Intent();

    intent.putExtra("add_more_friend_search_scene", 3);

    if (FTSAddFriendUI.this.iJw.rHc.size() > 1) {

    try {

    intent.putExtra("result", FTSAddFriendUI.this.iJw.toByteArray());

    C36379d.m70344b(FTSAddFriendUI.this.mController.tml, "subapp", ".ui.pluginapp.ContactSearchResultUI", intent);

    return;

    } catch (Throwable e) {

    C3327x.printErrStackTrace("MicroMsg.FTS.FTSAddFriendUI", e, "", new Object[0]);

    return;

    }

    }

    ((C33521h) C1261g.m2977l(C33521h.class)).mo24028a(intent, (biy) FTSAddFriendUI.this.iJw.rHc.getFirst(), FTSAddFriendUI.this.jvZ);

    }

    FTSAddFriendUI.this.jvX = 1;

    FTSAddFriendUI.m48692g(FTSAddFriendUI.this);

    }

    FTSAddFriendUI.m48693h(FTSAddFriendUI.this);

    }

    前面代码分析后无问题,但 if (FTSAddFriendUI.this.iJw.rHb > 0) 判断时不知rHb的值,此处需要hook一下。

    [Java] 纯文本查看 复制代码findAndHookMethod("com.tencent.mm.plugin.fts.ui.FTSAddFriendUI$5",loadPackageParam.classLoader,

    "a",int .class, int .class,String.class,XposedHelpers.findClass("com.tencent.mm.ab.l",loadPackageParam.classLoader) ,

    new XC_MethodHook() {

    @Override

    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

    super.beforeHookedMethod(param);

    log("FTSAddFriendUI$5--0="+param.args[0]+"=1="+param.args[1]+

    "=2="+param.args[2]+ "=rHb="+XposedHelpers.findField(XposedHelpers.findClass("com.tencent.mm.protocal.c.bja",loadPackageParam.classLoader),"rHb").get(XposedHelpers.callMethod((param.args[3]),"bcS"))

    );

    }

    打印得知rHb=0,所以不会走if语句内的代码,只有两个方法m48692g与m48693h有可能有问题,按顺序检查参数

    最终发现是这两个方法中使用了FTSAddFriendUI的变量bWm,而在输入框使用addTextChangedListener进行绑定后,bWm存储了输入的字符串,所以如果直接调用CM方法的话,导致bWm变量为空,所以解决方法如下:

    [Java] 纯文本查看 复制代码final Class FTSAddFriendUIClass=loadPackageParam.classLoader.loadClass("com.tencent.mm.plugin.fts.ui.FTSAddFriendUI");

    findAndHookMethod(FTSAddFriendUIClass,

    "onCreate",Bundle.class,

    new XC_MethodHook() {

    @Override

    protected void afterHookedMethod(final MethodHookParam param) throws Throwable {

    super.afterHookedMethod(param);

    new Handler().postDelayed(new Runnable() {

    @Override

    public void run() {

    XposedHelpers.setObjectField(param.thisObject,"bWm","微信号/QQ号/手机号");

    XposedHelpers.callMethod(param.thisObject,"CM","微信号/QQ号/手机号");

    }

    },1000);

    }

    });

    55fd2b2273b5a8b4531f72773c469d6e.gif

    2019-02-19 09_24_57.gif (739.03 KB, 下载次数: 8)

    2019-2-19 09:34 上传

    可以看到进入加好友界面后不需要输入,直接进入好友详情界面。

    当然如果输入数据搜索不到好友,结果处理方法的参数是

    2019-02-18 17:58:34.082 3872-3872/? I/Xposed: [17:58:34]:  FTSAddFriendUI$5--0=4=1=-4=2=User do not exist

    展开全文
  • 步骤1、分析qzone请求2、分析参数来源3、仿照数据请求上次写的一个qzone登陆写的不详细这次决定写一个详细分析qzone js 获取好友列表分析qzone请求...login_success.png你可能会说你在逗我,这特么哪里来的好友列...
  • JTree实现QQ好友列表

    2021-02-28 18:43:18
    实现TreeNode,在自定义好友列表的TreNode里面,需要显示好友的名字(uName),以及个性签名(text),然后是一个头像(img),然后ID是用来唯一标示该节点,存储的是好友的ID。然后是考虑到数型结构,会有孩子节点...
  • 实现微信好友列表

    2021-06-07 11:31:32
    实现微信好友列表ListView列表控件Android中的列表控件非常灵活,可以自定义每一个列表项,实际上每一个列表项就是一个View,在Android定义了3个列表控件:ListView、ExpandableListView和Spinner,其中Spinner...
  • 比如说好友面板不能随着窗口改变大小而改变,不过应该已经可以解决了,只是还没实践,下面就发上源代码: 一共有三个类: MemberModel.java //显示类QQ似好友标签信息的模板类; TestPane.java //添加多个模板的...
  • 好友列表查看好友资料$axure.utils.getTransparentGifPath = function() { return 'resources/images/transparent.gif'; };$axure.utils.getOtherPath = function() { return 'resources/Other.html'; };$axure....
  • 文件夹中的文件是微信的好友列表数据,冒号前是一个用,冒号后是该用户的所有好友(数据中的好友关系是单向的),参照笔记,求出哪些人两两之间有共同好友,及他俩的共同好友都有谁? 本题声明: 1.采用Linux系统 2....
  • JOptionPane.showMessageDialog(btnCha, "您查找的好友不在您的列表中!"); } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered...
  • android studio实现微信好友列表功能,注意有一个jar包我没有放上来,请大家到MainActivity中的那个网址里面下载即可,然后把pinyin4j-2.5.0.jar复制粘贴到项目的app/libs文件夹里面,然后clean项目就可以使用了实现...
  • 共同好友mysql

    2021-02-02 05:14:21
    1.好友关系传统:uid、 friendId缺陷:对于海量数据,100w用户,每人50个好友,则有 100w * 50的数据,数据量颇大改进1:分表根据uid hash成多个数据表,这样保障一个递增关系缺陷:处理共同好友、相识度问题...
  • 算法题之好友推荐

    2020-12-23 22:28:02
    题目要求:有n个人,每个人都有各自的好友列表。给定一个阈值p,当A和B的共同好友数超过p则推荐A和B为好友。请实现自动推荐直到没有好友可以推荐(每次推荐默认同意,即一定成为好友),然后进行一些查询。查询1:A的...
  • 功能设计查看群id查看指定id群的好友向指定群中所有自己的好友发送信息3.使用方法把代码复制粘贴,保存为 wxhelper.py在当前文件目录打开cmd指令窗口输入(windows系统)python wxhelper.py扫码登陆手机端向文件助手...
  • 领英如何设置好友谁可见 经常使用领英的人都知道,领英上面是可以查看到对方好友的,并且可以加对方的好友好友。同样自己的好友也可以被对方加走。有些好友可能是自己的客户,这样就会导致自己的客户补对方撬走。...
  • 仿QQ客户端 当前效果 登录界面 好友列表界面 当前效果 登录界面 首先,为了达到美观的目的,需要添加一张背景图片,我采用的方法是将图片添加到JLabel上,再将JLabel添加到界面上,但这样会面临一个问题——界面上的...
  • ': return # 向上滚动获取好友,获取好友会重复,最后结果需过滤 driver.swipe(100, 1000, 100, 500) # 递归循环得到所有好友 get_friends() 三、得到被对方删除的好友 在微信中被对方删除后,是不能进行转账的...
  • 安卓手机微信好友删了怎么找回?微信误删的好友怎么恢复回来呢?有人说我删了很久了,现在后混了想要把删除的好友再加回来,怎样操作才能成功恢复回来呢?根据数据恢复原理表明,就算是专业的数据恢复软件,也不可能...
  • 你先把你要找的人搜索出来,搜索位置在右上角 然后在搜索结果里面点击你找的那个人的名字 弹出他的主页以后,照片下方有个“加为好友” 等对方同意了。怎么加,详细一点,我是新手人人网由于对方的隐私设置,无法加...
  • 微信好友爬虫与分析

    2021-11-28 20:14:19
    微信一直是我们社交的重要渠道,甚至是我的唯一社交渠道,和父母、朋友、老师联系都是通过微信,那么一直依赖微信社交的你好奇你这么多好友的性别、城市、年龄及个性签名分布吗? 昨天浏览github时看到一个神奇的小...
  • 类型:社交聊天大小:62.5M语言:中文 评分:5.0标签:立即下载安卓版微信用户还是比较多的,最近有伙伴在询问如何找回被自己删除的好友,当不小心或者故意删除好友后,总会有一些伙伴想要重新找回好友,那么小编在...
  • 微信api接口,加好友及通过好友请求/*** 微信自动添加好友* @author wechatno:tangjinjinwx* @blog http://www.wlkankan.cn*/@Asyncpublic void handleMsg(ChannelHandlerContext ctx ,TransportMessage vo, String ...
  • 用python实现了模拟器点击功能,并实现了公招的操作,因此自己也弄了一个好友访问...1、好友线索赠送 2、好友访问 还有模拟器的分辨率为1024X576 一、连上模拟器 这段代码是复制b站大佬的,通过cmd调用adb指令连上mumu
  • 好友列表.html

    2021-06-11 06:00:46
    好友列表$axure.utils.getTransparentGifPath = function() { return 'resources/images/transparent.gif'; };$axure.utils.getOtherPath = function() { return 'resources/Other.html'; };$axure.utils....
  • 功能完成以后,就开始捣鼓AppleScript,发现微信并没有提供字典,我就尝试着进行了几个测试,看是否能通过特定的键盘操作实现找到好友,并给好友发送消息,接着尝试使用脚本来控制微信发消息,结果是成功的,相关...
  • MySQL好友

    2021-01-26 01:43:39
    小编典典假设所有朋友也都在用户表中,则需要一个朋友表,该表定义了简单的一对多关系-将用户表链接回自身。所以User TableUserID int identity not null[other attribute fields]Friends TableUserIDLink1 ...
  • 随着微信的使用时间越长,微信好友也越来越多,有些好友将你删除了你也不知道。当我们发消息的时候会出现下面扎心的一幕,然后默默将他删除 使用 Appium基础的 appium 使用在公众号文章 《解放双手,提高生产力,这...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 212,880
精华内容 85,152
关键字:

好友

友情链接: uart2spi_latest.tar.gz