最新用 Python 分析了 20 万场吃鸡数据_celery_battle,阿里21年面试题库

如果你也是看准了Python,想自学Python,在这里为大家准备了丰厚的免费学习大礼包,带大家一起学习,给大家剖析Python兼职、就业行情前景的这些事儿。

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、全套PDF电子书

书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

成为一个Python程序员专家或许需要花费数年时间,但是打下坚实的基础只要几周就可以,如果你按照我提供的学习路线以及资料有意识地去实践,你就有很大可能成功!
最后祝你好运!!!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 分析
  • 这个接口响应了战斗的详细信息,包括杀人数、爆头数、救人数、跑动距离等等,足够我们分析了。
  • 这个接口还响应了是被谁杀死的以及组团成员的openid,利用这个特性我们这可无限深度的发散爬取更多用户的数据。

至于cookie中的息pass_ticket等信息肯定是用于权限认证的,在上述的几次请求中这些信息都没有变化,所以我们不需要深研其是怎么算出来的,只需要抓包提取到默认信息后填到代码里面就可以用了。

Step 2 爬取数据

接口已经确定下来了,接下来就是去抓取足够量的数据了。

使用requests请求接口获取数据

 url = 'https://game.weixin.qq.com/cgi-bin/gamewap/getpubgmdatacenterindex?openid=%s&plat\_id=0&uin=&key=&pass\_ticket=%s' % (openid, settings.pass_ticket)
    r = requests.get(url=url, cookies=settings.def_cookies, headers=settings.def_headers, timeout=(5.0, 5.0))
    tmp = r.json()
    wfile = os.path.**join**(settings.Res_UserInfo_Dir, '%s.txt' % (rediskeys.user(openid)))
 
    with codecs.**open**(wfile, 'w', 'utf-8') **as** wf:
        wf.**write**(simplejson.dumps(tmp, indent=2, sort_keys=True, ensure_ascii=False))
'https://game.weixin.qq.com/cgi-bin/gamewap/getpubgmdatacenterindex?openid=%s&plat\_id=0&uin=&key=&pass\_ticket=%s' % (openid, settings.pass_ticket)
    r = requests.get(url=url, cookies=settings.def_cookies, headers=settings.def_headers, timeout=(5.0, 5.0))
    tmp = r.json()
    wfile = os.path.**join**(settings.Res_UserInfo_Dir, '%s.txt' % (rediskeys.user(openid)))
 
    with codecs.**open**(wfile, 'w', 'utf-8') **as** wf:
        wf.**write**(simplejson.dumps(tmp, indent=2, sort_keys=True, ensure_ascii=False))

参照这种方式我们可以很快把另外两个接口写好。

使用redis来标记已经爬取过的信息

在上述接口中我们可能从用户A的入口进去找到用户B的openid,然后从用户B的入口进去又找到用户A的openid,为了避免重复采集,所以我们需要记录下哪些信息是我们采集过的。 核心代码片断

# rediskeys.user\_battle\_list 根据openid获取存在redis中的key值
**def** **user\_battle\_list**(openid):
    **return** 'ubl\_%s' % (openid)
# 在提取battle list之前,首先判断这用用户的数据是否已经提取过了
**if** settings.DataRedis.get(rediskeys.user_battle_list(openid)):
        **return** **True**
# 在提取battle list之后,需要在redis中记录用户信息
settings.DataRedis.set(rediskeys.user_battle_list(openid), 1)

**def** **user\_battle\_list**(openid):
    **return** 'ubl\_%s' % (openid)
# 在提取battle list之前,首先判断这用用户的数据是否已经提取过了
**if** settings.DataRedis.get(rediskeys.user_battle_list(openid)):
        **return** **True**
# 在提取battle list之后,需要在redis中记录用户信息
settings.DataRedis.set(rediskeys.user_battle_list(openid), 1)

使用celery来管理队列

celery是一个非常好用的分布式队列管理工具,我这次只打算在我自己的电脑上运行,所以并没有用到分布式的功能。 我们创建三个task和三个queue

task_queues = (
    **Queue**('queue_get_battle_info', exchange=Exchange('priority', type='direct'), routing_key='gbi'),
    Queue('queue_get_battle_list', exchange=Exchange('priority', type='direct'), routing_key='gbl'),
    Queue('queue_get_user_info', exchange=Exchange('priority', type='direct'), routing_key='gui'),
)
 
task_routes = ([
    ('get_battle_info', {'queue': 'queue_get_battle_info'}),
    ('get_battle_list', {'queue': 'queue_get_battle_list'}),
    ('get_user_info', {'queue': 'queue_get_user_info'}),
],)
**Queue**('queue_get_battle_info', exchange=Exchange('priority', type='direct'), routing_key='gbi'),
    Queue('queue_get_battle_list', exchange=Exchange('priority', type='direct'), routing_key='gbl'),
    Queue('queue_get_user_info', exchange=Exchange('priority', type='direct'), routing_key='gui'),
)
 
task_routes = ([
    ('get_battle_info', {'queue': 'queue_get_battle_info'}),
    ('get_battle_list', {'queue': 'queue_get_battle_list'}),
    ('get_user_info', {'queue': 'queue_get_user_info'}),
],)

然后在task中控制API请求和Redis数据实现完整的任务逻辑,如:

@app.task(name='get\_battle\_list')
**def** **get\_battle\_list**(openid, plat_id=None, after_time=0, update_time=None):
    # 判断是否已经取过用户战绩列表信息
    **if** settings.DataRedis.get(rediskeys.user_battle_list(openid)):
        **return** **True**
 
    **if** **not** plat_id:
        **try**:
            # 提取用户信息
            us = handles.get_user_info_handles(openid)
            plat_id=us['plat\_id']
        **except** Exception **as** e:
            **print** 'can not get user plat\_id', openid, traceback.format_exc()
            **return** **False**
    # 提取战绩列表
    battle_list = handles.get_battle_list_handle(openid, plat_id, after_time=0, update_time=**None**)
    
    # 为每一场战斗创建异步获取详情任务
    **for** room_id **in** battle_list:
        **if** **not** settings.DataRedis.get(rediskeys.user_battle(openid, room_id)):
            get_battle_info.delay(openid, plat_id, room_id)
 
    **return** **True**

**def** **get\_battle\_list**(openid, plat_id=None, after_time=0, update_time=None):
    # 判断是否已经取过用户战绩列表信息
    **if** settings.DataRedis.get(rediskeys.user_battle_list(openid)):
        **return** **True**
 
    **if** **not** plat_id:
        **try**:
            # 提取用户信息
            us = handles.get_user_info_handles(openid)
            plat_id=us['plat\_id']
        **except** Exception **as** e:
            **print** 'can not get user plat\_id', openid, traceback.format_exc()
            **return** **False**
    # 提取战绩列表
    battle_list = handles.get_battle_list_handle(openid, plat_id, after_time=0, update_time=**None**)
    
    # 为每一场战斗创建异步获取详情任务
    **for** room_id **in** battle_list:
        **if** **not** settings.DataRedis.get(rediskeys.user_battle(openid, room_id)):
            get_battle_info.delay(openid, plat_id, room_id)
 
    **return** **True**

开始抓取

因为我们是发散是爬虫,所以需要给代码一个用户的入口,所以需要手动创建一个用户的采集任务

**from** tasks.all **import** get_battle_list
 
my_openid = 'oODfo0oIErZI2xxx9xPlVyQbRPgY'
my_platid = '0'
 
get_battle_list.delay(my_openid, my_platid, after_time=0, update_time=**None**)
 tasks.all **import** get_battle_list
 
my_openid = 'oODfo0oIErZI2xxx9xPlVyQbRPgY'
my_platid = '0'
 
get_battle_list.delay(my_openid, my_platid, after_time=0, update_time=**None**)

有入口之后我们就用celery来启动worker去开始爬虫

# 启动获取用户详情worker
**celery** -A tasks.all worker -c 5 --queue=queue_get_user_info --loglevel=info -n get_user_info@%h
 
# 启动获取战绩列表worker
celery -A tasks.all worker -c 5 --queue=queue_get_battle_list --loglevel=info -n get_battle_list@%h
 
# 启动获取战绩详情worker
celery -A tasks.all worker -c 30 --queue=queue_get_battle_info --loglevel=info -n get_battle_info@%h

**celery** -A tasks.all worker -c 5 --queue=queue_get_user_info --loglevel=info -n get_user_info@%h
 
# 启动获取战绩列表worker
celery -A tasks.all worker -c 5 --queue=queue_get_battle_list --loglevel=info -n get_battle_list@%h
 
# 启动获取战绩详情worker
celery -A tasks.all worker -c 30 --queue=queue_get_battle_info --loglevel=info -n get_battle_info@%h

这样我们的爬虫就可以愉快的跑起来了。再通过celery-flower来查看执行情况。

**celery** flower -A tasks.all --broker=redis://:$REDIS\_PASS@$REDIS\_HOST:$REDIS\_PORT/10
 flower -A tasks.all --broker=redis://:$REDIS\_PASS@$REDIS\_HOST:$REDIS\_PORT/10

通过flower,我们可以看到运行的效率还是非常不错的。外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在执行过程中会发现get_battle_list跑太快,导致get_battle_info即使开了30个并发都还会积压很多,所以需要适时的去停一下这些worker。 在我们抓到20万条信息之后就可以停下来了。

Step 3 数据分析

分析方案

20万场战斗的数据已经抓取好了,全部分成json文件存在我本地磁盘上,接下来就做一些简单的分析。 python在数据分析领域也非常强大,有很多非常优秀的库,如pandas和NumPy,可惜我都没有学过,而且对于一个高考数学只考了70几分的人来说,数据分析实在是难,所以就自己写了一个非常简单的程序来做一些浅度分析。 需要进行深度分析,又不想自己爬虫的大牛可以联系我打包这些数据。

# coding=utf-8
**import** os
**import** json
**import** datetime
**import** math
 
**from** conf **import** settings
 
 
**class** **UserTeamTypeData**:
    **def** **\_\_init\_\_**(self, team_type, player_count):
        self.team_type = team_type
        self.player_count = player_count
        self.label = {}
        self.dead_poison_circle_no = {}
        self.count = 0
        self.damage = 0
        self.survival_duration = 0  # 生存时间
        self.driving_distance = 0
        self.forward_distance = 0
        self.times_assist = 0  # 助攻
        self.times_head_shot = 0
        self.times_kill = 0
        self.times_reborn = 0  # 被救次数
        self.times_save = 0  # 救人次数
        self.top_kill_distance = []
        self.top_kill_distance_weapon_use = {}
        self.vehicle_kill = 0  # 车辆杀死
        self.award_gold = 0
        self.times_reborn_by_role_sex = {0: 0, 1: 0}  # 0 男 1 女
        self.times_save_by_role_sex = {0: 0, 1: 0}  # 0 男 1 女
 
    **def** **update\_dead\_poison\_circle\_no**(self, dead_poison_circle_no):
        **if** dead_poison_circle_no **in** self.dead_poison_circle_no:
            self.dead_poison_circle_no[dead_poison_circle_no] += 1
        **else**:
            self.dead_poison_circle_no[dead_poison_circle_no] = 1
 
    **def** **update\_times\_reborn\_and\_save\_by\_role\_sex**(self, role, times_reborn, times_save):
        **if** role **not** **in** self.times_reborn_by_role_sex:
            **return**
 
        self.times_reborn_by_role_sex[role] += times_reborn
        self.times_save_by_role_sex[role] += times_save
 
    **def** **update\_top\_kill\_distance\_weapon\_use**(self, weaponid):
        **if** weaponid **not** **in** self.top_kill_distance_weapon_use:
            self.top_kill_distance_weapon_use[weaponid] = 1
        **else**:
            self.top_kill_distance_weapon_use[weaponid] += 1
 
 
**class** **UserBattleData**:
 
    **def** **\_\_init\_\_**(self, openid):
        self.openid = openid
        self.team_type_res = {}
        self.label = {}
        self.hour_counter = {}
        self.weekday_counter = {}
        self.usetime = 0
        self.day_record = set()
        self.battle_counter = 0
 
    **def** **get\_avg\_use\_time\_per\_day**(self):
        # print "get\_avg\_use\_time\_per\_day:", self.openid, self.usetime, len(self.day\_record), self.usetime / len(self.day\_record)
        **return** self.usetime / len(self.day_record)
 
    **def** **update\_label**(self, lable):
        **if** lable **in** self.label:
            self.label[lable] += 1
        **else**:
            self.label[lable] = 1
 
    **def** **get\_team\_type\_data**(self, team_type, player_count):
        player_count = int(math.ceil(float(player_count) / 10))
        team_type_key = '%d\_%d' % (team_type, player_count)
 
        **if** team_type_key **not** **in** self.team_type_res:
            userteamtypedata = UserTeamTypeData(team_type, player_count)
            self.team_type_res[team_type_key] = userteamtypedata
        **else**:
            userteamtypedata = self.team_type_res[team_type_key]
 
        **return** userteamtypedata
 
    **def** **update\_user\_time\_property**(self, dt_event_time):
        dt_event_time = datetime.datetime.fromtimestamp(dt_event_time)
        hour = dt_event_time.hour
        **if** hour **in** self.hour_counter:
            self.hour_counter[hour] += 1
        **else**:
            self.hour_counter[hour] = 1
 
        weekday = dt_event_time.weekday()
        **if** weekday **in** self.weekday_counter:
            self.weekday_counter[weekday] += 1
        **else**:
            self.weekday_counter[weekday] = 1
 
        self.day_record.add(dt_event_time.date())
 
    **def** **update\_battle\_info\_by\_room**(self, roomid):
        # print '  load ', self.openid, roomid
        file = os.path.join(settings.Res_UserBattleInfo_Dir, self.openid, '%s.txt' % roomid)
 
        **with** open(file, 'r') **as** rf:
            battledata = json.load(rf)
 
        self.battle_counter += 1
        base_info = battledata['base\_info']
        self.update_user_time_property(base_info['dt\_event\_time'])
        battle_info = battledata['battle\_info']
 
        userteamtypedata = self.get_team_type_data(base_info['team\_type'], base_info['player\_count'])
        userteamtypedata.count += 1
        userteamtypedata.award_gold += battle_info['award\_gold']
        userteamtypedata.damage += battle_info['damage']
        userteamtypedata.update_dead_poison_circle_no(battle_info['dead\_poison\_circle\_no'])
        userteamtypedata.driving_distance += battle_info['driving\_distance']
        userteamtypedata.forward_distance += battle_info['forward\_distance']
        self.update_label(battle_info['label'])
        userteamtypedata.survival_duration += battle_info['survival\_duration']
        self.usetime += battle_info['survival\_duration']/60
        userteamtypedata.times_assist += battle_info['times\_assist']
        userteamtypedata.times_head_shot += battle_info['times\_head\_shot']
        userteamtypedata.times_kill += battle_info['times\_kill']
        userteamtypedata.times_reborn += battle_info['times\_reborn']
        userteamtypedata.times_save += battle_info['times\_save']
        userteamtypedata.damage += battle_info['damage']
        userteamtypedata.top_kill_distance.append(battle_info['top\_kill\_distance'])
        userteamtypedata.update_times_reborn_and_save_by_role_sex(base_info['role\_sex'], battle_info['times\_reborn'],
                                                                  battle_info['times\_save'])
 
    **def** **get\_user\_battleinfo\_rooms**(self):
        user_dir = os.path.join(settings.Res_UserBattleInfo_Dir, self.openid)
        r = [room **for** room **in** os.listdir(user_dir)]
        r = [rr.replace('.txt', '') **for** rr **in** r]
        **return** r
 
**class** **AllUserCounter**:
 
    **def** **\_\_init\_\_**(self):
        self.hour_counter = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0, 21: 0, 22: 0, 23: 0}
 
        self.weekday_counter = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0}
        self.times_reborn_by_role_sex = {0: 0, 1: 0}  # 0 男 1 女
        self.times_save_by_role_sex = {0: 0, 1: 0}  # 0 男 1 女
        self.user_count = 0
        self.battle_count = 0
        self.every_user_use_time_per_day = []
        self.top_kill_distance = 0
 
    **def** **avg\_use\_time**(self):
        **return** sum(self.every_user_use_time_per_day) / len(self.every_user_use_time_per_day)
 
    **def** **add\_user\_data**(self, userbattledata):
        self.every_user_use_time_per_day.append(userbattledata.get_avg_use_time_per_day())
        self.battle_count += userbattledata.battle_counter
        self.user_count += 1
 
        **for** k **in** userbattledata.hour_counter:
            **if** k **in** self.hour_counter:
                self.hour_counter[k] += userbattledata.hour_counter[k]
            **else**:
                self.hour_counter[k] = userbattledata.hour_counter[k]
 
        **for** weekday **in** userbattledata.weekday_counter:
            **if** weekday **in** self.weekday_counter:
                self.weekday_counter[weekday] += userbattledata.weekday_counter[weekday]
            **else**:
                self.weekday_counter[weekday] = userbattledata.weekday_counter[weekday]
 
        **for** userteamtype **in** userbattledata.team_type_res:
            userteamtypedata = userbattledata.team_type_res[userteamtype]
            **for** k **in** userteamtypedata.times_reborn_by_role_sex:
                self.times_reborn_by_role_sex[k] += userteamtypedata.times_reborn_by_role_sex[k]
 
            **for** k **in** userteamtypedata.times_save_by_role_sex:
                self.times_save_by_role_sex[k] += userteamtypedata.times_save_by_role_sex[k]
 
            **if** userteamtypedata.top_kill_distance > self.top_kill_distance:
                self.top_kill_distance = userteamtypedata.top_kill_distance
 
    **def** **\_\_str\_\_**(self):
        res = []
        res.append('总用户数\t%d' % self.user_count)
        res.append('总战斗数\t%d' % self.battle_count)
        res.append('平均日耗时\t%d' % self.avg_use_time())
        res.append('最远击杀\t%d' % max(self.top_kill_distance))
        res.append('男性角色\t被救%d次\t救人%d次' % (self.times_reborn_by_role_sex[0], self.times_save_by_role_sex[0]))
        res.append('女性角色\t被救%d次\t救人%d次' % (self.times_reborn_by_role_sex[1], self.times_save_by_role_sex[1]))
 
        res.append('小时分布')
        **for** hour **in** range(0, 24):
            # res.append('\t%d: %d' % (hour, self.hour\_counter[hour]))
            res.append('\t%d: %d %.2f%%' % (hour, self.hour_counter[hour], self.hour_counter[hour]/float(self.battle_count)*100))
        res.append('星期分布')
        # res.append(self.weekday\_counter.\_\_str\_\_())
        **for** weekday **in** range(0, 7):
            res.append('\t%d: %d %.2f%%' % (weekday+1, self.weekday_counter[weekday], (self.weekday_counter[weekday]/float(self.battle_count)*100)))
 
        **return** '\n'.join(res)
 
 
**def** **get\_user\_battleinfo\_rooms**(openid):
    user_dir = os.path.join(settings.Res_UserBattleInfo_Dir, openid)
 
    # files = os.listdir(user\_dir)
    r = [room **for** room **in** os.listdir(user_dir)]
    r = [rr.replace('.txt', '') **for** rr **in** r]
    **return** r
 
 
**if** __name__ == '\_\_main\_\_':
    alluserconter = AllUserCounter()
    
    folders = os.listdir(settings.Res_UserBattleInfo_Dir)
    i = 0
    **for** folder **in** folders:
        i+=1
        **print** i, '/' , len(folders), folder
        userbattledata = UserBattleData(folder)
        **for** room **in** userbattledata.get_user_battleinfo_rooms():
            userbattledata.update_battle_info_by_room(room)
        alluserconter.add_user_data(userbattledata)
 
    **print** "\n" * 3
    **print** "---------------------------------------"
 
    **print** alluserconter

**import** os
**import** json
**import** datetime
**import** math
 
**from** conf **import** settings
 
 
**class** **UserTeamTypeData**:
    **def** **\_\_init\_\_**(self, team_type, player_count):
        self.team_type = team_type
        self.player_count = player_count
        self.label = {}
        self.dead_poison_circle_no = {}
        self.count = 0
        self.damage = 0
        self.survival_duration = 0  # 生存时间
        self.driving_distance = 0
        self.forward_distance = 0
        self.times_assist = 0  # 助攻
        self.times_head_shot = 0
        self.times_kill = 0
        self.times_reborn = 0  # 被救次数
        self.times_save = 0  # 救人次数
        self.top_kill_distance = []
        self.top_kill_distance_weapon_use = {}
        self.vehicle_kill = 0  # 车辆杀死
        self.award_gold = 0
        self.times_reborn_by_role_sex = {0: 0, 1: 0}  # 0 男 1 女
        self.times_save_by_role_sex = {0: 0, 1: 0}  # 0 男 1 女
 
    **def** **update\_dead\_poison\_circle\_no**(self, dead_poison_circle_no):
        **if** dead_poison_circle_no **in** self.dead_poison_circle_no:
            self.dead_poison_circle_no[dead_poison_circle_no] += 1
        **else**:
            self.dead_poison_circle_no[dead_poison_circle_no] = 1
 
    **def** **update\_times\_reborn\_and\_save\_by\_role\_sex**(self, role, times_reborn, times_save):
        **if** role **not** **in** self.times_reborn_by_role_sex:
            **return**
 
        self.times_reborn_by_role_sex[role] += times_reborn
        self.times_save_by_role_sex[role] += times_save
 
    **def** **update\_top\_kill\_distance\_weapon\_use**(self, weaponid):
        **if** weaponid **not** **in** self.top_kill_distance_weapon_use:
            self.top_kill_distance_weapon_use[weaponid] = 1
        **else**:
            self.top_kill_distance_weapon_use[weaponid] += 1
 
 
**class** **UserBattleData**:
 
    **def** **\_\_init\_\_**(self, openid):
        self.openid = openid
        self.team_type_res = {}
        self.label = {}
        self.hour_counter = {}
        self.weekday_counter = {}
        self.usetime = 0
        self.day_record = set()
        self.battle_counter = 0
 
    **def** **get\_avg\_use\_time\_per\_day**(self):
        # print "get\_avg\_use\_time\_per\_day:", self.openid, self.usetime, len(self.day\_record), self.usetime / len(self.day\_record)
        **return** self.usetime / len(self.day_record)
 
    **def** **update\_label**(self, lable):
        **if** lable **in** self.label:
            self.label[lable] += 1
        **else**:
            self.label[lable] = 1
 
    **def** **get\_team\_type\_data**(self, team_type, player_count):
        player_count = int(math.ceil(float(player_count) / 10))
        team_type_key = '%d\_%d' % (team_type, player_count)
 
        **if** team_type_key **not** **in** self.team_type_res:
            userteamtypedata = UserTeamTypeData(team_type, player_count)
            self.team_type_res[team_type_key] = userteamtypedata
        **else**:
            userteamtypedata = self.team_type_res[team_type_key]
 
        **return** userteamtypedata
 
    **def** **update\_user\_time\_property**(self, dt_event_time):
        dt_event_time = datetime.datetime.fromtimestamp(dt_event_time)
        hour = dt_event_time.hour
        **if** hour **in** self.hour_counter:
            self.hour_counter[hour] += 1
        **else**:
            self.hour_counter[hour] = 1
 
        weekday = dt_event_time.weekday()
        **if** weekday **in** self.weekday_counter:
            self.weekday_counter[weekday] += 1
        **else**:
            self.weekday_counter[weekday] = 1
 
        self.day_record.add(dt_event_time.date())
 
    **def** **update\_battle\_info\_by\_room**(self, roomid):
        # print '  load ', self.openid, roomid
        file = os.path.join(settings.Res_UserBattleInfo_Dir, self.openid, '%s.txt' % roomid)
 
        **with** open(file, 'r') **as** rf:
            battledata = json.load(rf)
 
        self.battle_counter += 1
        base_info = battledata['base\_info']
        self.update_user_time_property(base_info['dt\_event\_time'])
        battle_info = battledata['battle\_info']
 
        userteamtypedata = self.get_team_type_data(base_info['team\_type'], base_info['player\_count'])
        userteamtypedata.count += 1
        userteamtypedata.award_gold += battle_info['award\_gold']
        userteamtypedata.damage += battle_info['damage']
        userteamtypedata.update_dead_poison_circle_no(battle_info['dead\_poison\_circle\_no'])
        userteamtypedata.driving_distance += battle_info['driving\_distance']
        userteamtypedata.forward_distance += battle_info['forward\_distance']
        self.update_label(battle_info['label'])
        userteamtypedata.survival_duration += battle_info['survival\_duration']
        self.usetime += battle_info['survival\_duration']/60
        userteamtypedata.times_assist += battle_info['times\_assist']
        userteamtypedata.times_head_shot += battle_info['times\_head\_shot']
        userteamtypedata.times_kill += battle_info['times\_kill']
        userteamtypedata.times_reborn += battle_info['times\_reborn']
        userteamtypedata.times_save += battle_info['times\_save']
        userteamtypedata.damage += battle_info['damage']
        userteamtypedata.top_kill_distance.append(battle_info['top\_kill\_distance'])
        userteamtypedata.update_times_reborn_and_save_by_role_sex(base_info['role\_sex'], battle_info['times\_reborn'],
                                                                  battle_info['times\_save'])
 
    **def** **get\_user\_battleinfo\_rooms**(self):
        user_dir = os.path.join(settings.Res_UserBattleInfo_Dir, self.openid)
        r = [room **for** room **in** os.listdir(user_dir)]
        r = [rr.replace('.txt', '') **for** rr **in** r]
        **return** r
 
**class** **AllUserCounter**:
 
    **def** **\_\_init\_\_**(self):
        self.hour_counter = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, 15: 0, 16: 0, 17: 0, 18: 0, 19: 0, 20: 0, 21: 0, 22: 0, 23: 0}
 
        self.weekday_counter = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0}
        self.times_reborn_by_role_sex = {0: 0, 1: 0}  # 0 男 1 女
        self.times_save_by_role_sex = {0: 0, 1: 0}  # 0 男 1 女
        self.user_count = 0
        self.battle_count = 0
        self.every_user_use_time_per_day = []
        self.top_kill_distance = 0
 
    **def** **avg\_use\_time**(self):
        **return** sum(self.every_user_use_time_per_day) / len(self.every_user_use_time_per_day)
 
    **def** **add\_user\_data**(self, userbattledata):
        self.every_user_use_time_per_day.append(userbattledata.get_avg_use_time_per_day())
        self.battle_count += userbattledata.battle_counter
        self.user_count += 1
 
        **for** k **in** userbattledata.hour_counter:
            **if** k **in** self.hour_counter:
                self.hour_counter[k] += userbattledata.hour_counter[k]
            **else**:
                self.hour_counter[k] = userbattledata.hour_counter[k]
 
        **for** weekday **in** userbattledata.weekday_counter:
            **if** weekday **in** self.weekday_counter:
                self.weekday_counter[weekday] += userbattledata.weekday_counter[weekday]
            **else**:
                self.weekday_counter[weekday] = userbattledata.weekday_counter[weekday]
 
        **for** userteamtype **in** userbattledata.team_type_res:
            userteamtypedata = userbattledata.team_type_res[userteamtype]
            **for** k **in** userteamtypedata.times_reborn_by_role_sex:
                self.times_reborn_by_role_sex[k] += userteamtypedata.times_reborn_by_role_sex[k]
 
            **for** k **in** userteamtypedata.times_save_by_role_sex:
                self.times_save_by_role_sex[k] += userteamtypedata.times_save_by_role_sex[k]
 
            **if** userteamtypedata.top_kill_distance > self.top_kill_distance:
                self.top_kill_distance = userteamtypedata.top_kill_distance
 
    **def** **\_\_str\_\_**(self):
        res = []
        res.append('总用户数\t%d' % self.user_count)
        res.append('总战斗数\t%d' % self.battle_count)
        res.append('平均日耗时\t%d' % self.avg_use_time())
        res.append('最远击杀\t%d' % max(self.top_kill_distance))
        res.append('男性角色\t被救%d次\t救人%d次' % (self.times_reborn_by_role_sex[0], self.times_save_by_role_sex[0]))
        res.append('女性角色\t被救%d次\t救人%d次' % (self.times_reborn_by_role_sex[1], self.times_save_by_role_sex[1]))
 
        res.append('小时分布')
        **for** hour **in** range(0, 24):
            # res.append('\t%d: %d' % (hour, self.hour\_counter[hour]))
            res.append('\t%d: %d %.2f%%' % (hour, self.hour_counter[hour], self.hour_counter[hour]/float(self.battle_count)*100))
        res.append('星期分布')
        # res.append(self.weekday\_counter.\_\_str\_\_())
        **for** weekday **in** range(0, 7):
            res.append('\t%d: %d %.2f%%' % (weekday+1, self.weekday_counter[weekday], (self.weekday_counter[weekday]/float(self.battle_count)*100)))
 
        **return** '\n'.join(res)
 
 
**def** **get\_user\_battleinfo\_rooms**(openid):
    user_dir = os.path.join(settings.Res_UserBattleInfo_Dir, openid)
 
    # files = os.listdir(user\_dir)
    r = [room **for** room **in** os.listdir(user_dir)]
    r = [rr.replace('.txt', '') **for** rr **in** r]
    **return** r
 
 
**if** __name__ == '\_\_main\_\_':
    alluserconter = AllUserCounter()
    
    folders = os.listdir(settings.Res_UserBattleInfo_Dir)
    i = 0
    **for** folder **in** folders:
        i+=1
        **print** i, '/' , len(folders), folder
        userbattledata = UserBattleData(folder)
        **for** room **in** userbattledata.get_user_battleinfo_rooms():
            userbattledata.update_battle_info_by_room(room)
        alluserconter.add_user_data(userbattledata)
 
    **print** "\n" * 3
    **print** "---------------------------------------"
 
    **print** alluserconter

分析结果

1. 平均用户日在线时长2小时

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传从分布图上看大部分用户都在1小时以上,最猛的几个人超过8小时。

注:我这里统计的是每一局的存活时间,实际在线时长会比我这个更长。

2. 女性角色被救次数高于男性

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传终于知道为什么有那么多人妖了,原来在游戏里面可以占便宜啊。

3. 女性角色救人次数高于男性

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传给了大家一个带妹上分的好理由。

4. 周五大家最忙

现在能在网上找到很多很多的学习资源,有免费的也有收费的,当我拿到1套比较全的学习资源之前,我并没着急去看第1节,我而是去审视这套资源是否值得学习,有时候也会去问一些学长的意见,如果可以之后,我会对这套学习资源做1个学习计划,我的学习计划主要包括规划图和学习进度表。

分享给大家这份我薅到的免费视频资料,质量还不错,大家可以跟着学习

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

uY-1715135884168)]从分布图上看大部分用户都在1小时以上,最猛的几个人超过8小时。

注:我这里统计的是每一局的存活时间,实际在线时长会比我这个更长。

2. 女性角色被救次数高于男性

[外链图片转存中…(img-AW0NbFJ2-1715135884169)]终于知道为什么有那么多人妖了,原来在游戏里面可以占便宜啊。

3. 女性角色救人次数高于男性

[外链图片转存中…(img-fyJRn8Na-1715135884170)]给了大家一个带妹上分的好理由。

4. 周五大家最忙

现在能在网上找到很多很多的学习资源,有免费的也有收费的,当我拿到1套比较全的学习资源之前,我并没着急去看第1节,我而是去审视这套资源是否值得学习,有时候也会去问一些学长的意见,如果可以之后,我会对这套学习资源做1个学习计划,我的学习计划主要包括规划图和学习进度表。

分享给大家这份我薅到的免费视频资料,质量还不错,大家可以跟着学习

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值