王者荣耀故此python的requests第三正模块抓取王者荣耀所有勇于的肌肤

本文使用python的老三正值模块requests爬取王者荣耀所有勇于之图,并以图片按照每个英雄呢一个目存入文件夹着,方便作桌面壁纸

立马是天子荣耀技术分析系列第三首,有趣味请持续关注。

1、诸如《王者荣耀》一种红了

2、自打《王者荣耀》来聊天游戏的轴同步

3、游戏服务器的架构演进

脚时具体的代码,已经过python3.6测试,可以成功运行:

 

对此所而爬取的网页连接可以由此上荣耀官网找到,

本文阅读预计用10分钟,主要技术点来如下,感兴趣请继续:

  1 # -*- coding: utf-8 -*-
  2 """
  3 Created on Wed Dec 13 13:49:52 2017
  4 
  5 @author:KillerTwo
  6 """
  7 import requests
  8 import os
  9 hero_list_url = 'http://pvp.qq.com/web201605/js/herolist.json'
 10 hero_skin_root_url = 'http://game.gtimg.cnyxzj/img201606/skin/hero-info/'
 11 skin_base_dir = 'C:\\Users\\lwt27\\Pictures\\image\\heroskin\\'
 12 
 13 
 14 def get_ename(hero_json):#传入获取到的python对象,如hero_list_json
 15     '''获取英雄名称对应英雄编号的一个字典,例如{小乔:106,...}'''
 16     cname_ename = {}
 17     for hero in hero_json:
 18         cname_ename[hero['cname']] = hero['ename']
 19     return cname_ename
 20 
 21 def get_skin_name(hero_json): #传入从网页获取到的json转换为python字典的对象
 22     '''获取英雄名称对应的皮肤的所有皮肤名称的字典,例如
 23     {'小乔':'恋之微风|万圣前夜|天鹅之梦|纯白花嫁|缤纷独角兽',...}'''
 24     cname_skin_name = {}
 25     for hero in hero_json:
 26         cname_skin_name[hero['cname']] = hero['skin_name']
 27     return cname_skin_name
 28 
 29 def get_hero_skin_count(cname_skin_name): #传入英雄名称对应皮肤名称的字典
 30     '''获取每个英雄对应的皮肤的个数,例如{'小乔':5,...}'''
 31     cname_skin_count = {} 
 32     for item in cname_skin_name.items():
 33         cname_skin_count[item[0]] = len(item[1].split('|'))
 34     return cname_skin_count
 35 
 36 def get_skin_name_url(skin_base_rul,cname_skin_count,cname_ename):
 37     #传入皮肤根地址和名称对应皮肤数量的字典和名称对应编号的字典
 38     '''返回英雄名称对应的所有皮肤的url地址列表的字典,例如{小乔:[skin_url1,skin_url2],...}'''
 39     cname_url_list = {}
 40     for cname,count in cname_skin_count.items():
 41         #print(cname)
 42         #print(count)
 43         #print(skin_base_rul)
 44         #print(cname_ename[cname])
 45         base_url = skin_base_rul+str(cname_ename[cname])+'/'+str(cname_ename[cname])+'-bigskin-'
 46         #print(base_url)
 47         skin_url_list = [str(base_url)+str(num)+'.jpg' for num in range(1,count+1)]
 48         cname_url_list[cname] = skin_url_list
 49     return cname_url_list
 50 
 51 #print()
 52 d = get_skin_name_url(hero_skin_root_url,get_hero_skin_count(get_skin_name(hero_list_json)),get_ename(hero_list_json))
 53 #print(d)
 54 
 55 def get_cname_skin_name(cname_skin_name):#传入名称对应皮肤名称字符串的字典
 56     cname_skin_name_dict = {}         #返回名称对应【皮肤名称的列表】的字典
 57     for cname,skin_name_list in cname_skin_name.items():
 58         skin_list = [name for name in skin_name_list.split('|')]
 59         cname_skin_name_dict[cname] = skin_list
 60     return cname_skin_name_dict
 61     
 62 #s = get_skin_name(hero_list_json)
 63 #print(s)
 64 #f = get_cname_skin_name(s)
 65 #print(f)
 66 
 67 def get_hero_skin(cname_url_list,cname_skin_name):#传入名称对应【皮肤名称列表】的字典和名称对应皮肤url列表的字典
 68    # """获取每个英雄的图片"""
 69     for cname,skin_url in cname_url_list.items():
 70         
 71         if mkdir(skin_base_dir+cname):#创建指定目录
 72             os.chdir(skin_base_dir+cname)  #进入到创建的目录
 73             
 74             for i in range(len(skin_url)):
 75                 file_name = cname_skin_name[cname][i]+'.jpg'
 76                 r = requests.get(skin_url[i])
 77                 with open(file_name,'wb') as f:
 78                     f.write(r.content)
 79 #创建目录
 80 def mkdir(path):
 81     # 引入模块
 82     import os
 83     # 去除首位空格
 84     path=path.strip()
 85     # 去除尾部 \ 符号
 86     path=path.rstrip("\\")
 87     # 判断路径是否存在
 88     # 存在     True
 89     # 不存在   False
 90     isExists=os.path.exists(path)
 91     # 判断结果
 92     if not isExists:
 93         # 如果不存在则创建目录
 94         # 创建目录操作函数
 95         os.makedirs(path)
 96         print(path+' 创建成功')
 97         return True
 98     else:
 99         # 如果目录存在则不创建,并提示目录已存在
100         print(path+' 目录已存在')
101         return False
102     return 
103 
104 if __name__ == '__main__':
105     
106     hero_list_body = requests.get(hero_list_url) #请求英雄列表
107     hero_list_json = hero_list_body.json()  #将英雄列表的获取的json数据转换为python对象
108 
109     cname_ename = {}       #英雄名称对应英雄编号的字典
110     cname__skin_name = {} #英雄名称对应皮肤名称字符串的字典
111     cname_skin_count = {} #英雄名称对应皮肤数量的字典
112     
113     cname_skin_name_str_list = get_skin_name(hero_list_json)
114     cname_skin_name_list = get_cname_skin_name(cname_skin_name_str_list)
115     cname_skin_count = get_hero_skin_count(cname_skin_name_str_list)
116     cname_ename = get_ename(hero_list_json)
117     cnam_skin_url_list = get_skin_name_url(hero_skin_root_url,cname_skin_count,cname_ename)
118     get_hero_skin(cnam_skin_url_list,cname_skin_name_list)

 

  1. 娱服务器特征

  2. 短连接游戏服务器架设

  3. 长链接游戏服务器架设

  4. 分区分服服务器架设

  5. MMOARPG服务器架设

  6. 房间服务器架设

 

下面是保存抓取到之图片的文书夹样例:

1游戏服务器特征

王者荣耀 1

 

上述就是是抓取王者荣耀所有勇于皮肤之简练示例,上述的代码并不曾动python多线程执行抓取图片的函数,所以当实施的时候也许需要花费几分钟之时刻,

打服务器端,是一个见面长久运行的次第,并且它们还要服务让多单天翻地覆时,不定点的网络要。所以马上看似软件之表征是要大关心稳定性以及总体性。这类似程序一旦要多单合作来提高承载能力,则还要体贴部署与扩容的便利性;同时,还欲考虑什么促成某种程度容灾需求。由于多进程协同工作,也牵动了开支的复杂度,这为是用关爱之问题。

后来在展开改善,添加应用python多线程执行抓取任务。

 

 

力量约束,是架构设计决定性因素。基于游戏领域的法力特色,对劳务器端系统来说,有以下几单非常的需求:

  1. 对游戏数量及玩家数量的存储

  2. 针对玩家数据开展数量广播和协同

  3. 将一些戏逻辑在服务器上运算,做好征,防止外挂。

     

 

对以上的需特点,在劳务器端,我们一再会关注对电脑内存和CPU的使,以求于一定业务代码下,能尽可能满足承载量和响应延迟的要求。最中心的做法就是“空间更换时间”,用各种缓存的措施来为求得CPU和内存空间上的平衡。

 

每当CPU和内存之上,是另外一个束缚因素:网卡。网络带来富直接限制了服务器的拍卖能力,所以戏服务器架设也定要考虑这个因素。

 

 

2戏服务器架设要素

    对于游戏服务端架构,最要害的老三单部分即使是,如何运用CPU、内存、网卡的计划:

 

内存架构:主要控制服务器如何以内存,以最大化利用服务器端内存来提高承载量,降低服务延迟。

 

逻辑架构:设计怎么样利用过程、线程、协程这些对于CPU调度的方案。选择并、异步等不等之编程模型,以增长服务器的安宁与承载量。可以分区分服,也可行使世界服的法门,将同功能模块划分到不同之服务器来处理。

 

通信模式:决定采取何种方法通讯。基于游戏项目不同应用不同的通信模式,比如http,tcp,udp等。

 

 

3服务器演化过程

 

1卡牌等休闲游戏弱交互游戏

 

服务器基于游戏类不同,所下的架构也迥然不同,我们先行称一下粗略的模子,采用http通信模式架构的服务器:

王者荣耀 2

 

这种服务器架设和我们常因此底web服务器架构差不多,也是采用nginx负载集群支持服务器的程度扩展,memcache做缓存。

 

唯不同之地址不同的在于通信层需要针对协议还加工以及加密,一般每个公司还产生好的一致效基于http的商事层框架,很少使开源框架。

 

 

2长链接游戏服务器

 

加上连游戏和弱联网游戏不同的地方在于,长连接中,玩家是发状态的,服务器可以随时与client交互,数据的传递,不像弱联网一般每次都需更创设一个总是,消息传送的效率与速度及还抢吃弱联网游戏。

 

 

1、第一替代网游服务器(单线程无阻塞)

不过早的玩服务器是1978年,英国显赫一时的金融学校University of Essex的学生 Roy Trubshaw编写了世道上第一独MUD程序,叫做《MUD1》。

 

 

《MUD1》程序的源代码在 ARPANET共享后,在环球广泛流行起来。不断完善的
MUD1的根基及有了开源的 MudOS(1991),成为众网游的高祖。

 

MUD1
是一律款款纯粹文字的社会风气,没有其余图片,但是不同电脑前之玩家可于戏里并冒险、交流。

暨以往享有网络合功能的游艺相比,
MUD1凡是首先放缓真含义及的实时差不多丁互相的网络游戏,它极充分之特点是能保证全体虚拟世界和玩家角色的不停上扬——无论是玩家退出后再次登录要服务器再开,游戏受之情景、宝箱、怪物与谜题仍保持不移,玩家的角色也一如既往是上次底状态。

 

王者荣耀 3

 

MUDOS使用单线程无阻塞套接字来服务具有玩家,所有玩家的呼吁都作到和一个线程去处理,主线程每隔1秒钟更新一糟糕有目标(网络收发,对象状态,刷新地图,刷新NPC)。

 

用户以 Telnet之类的客户端用 Tcp协议连接至
MUDOS上,使用纯文字进行打,每条指令用回车进行划分。这样的体系以马上诸台服务器承载个4000口又玩。从1991年之
MUDOS发布后,全球各地都于也外改进,扩充,推出新本子。

 

MUDOS中玩耍内容通过
LPC脚论进行定制,逻辑处理下单线程tick轮询,这吗是首先舒缓服务端架构模型,后来受以至不同游戏达到。后续很多逛戏还是暨《UO》一样,直接在
MUDOS上进行二次开发,直到
如今,一些回合制游戏,以及针对性运算量小之玩耍,依然采用这种服务器架设。

 

先是替服务器架构图:

王者荣耀 4

线程模型

王者荣耀 5

 

 

2、第二代表网游服务器(分区分服)

2000年左右,随着图形界面的出现,游戏再多的利用图形界面与用户交互。此时乘在线人数的多及打数量的加,服务器移得无抗重负。于是就生了分服模型。分服模型结构如下:

 

王者荣耀 6

 

分服模型是戏服务器受到极度特异,也是有史以来最遥远的型。在首服务器的承载量达到上限的时段,游戏开发者就通过架设更多的服务器来化解。这样提供了成千上万只戏的“平行世界”,让戏受之人们之间的于,产生了还多的半空中。

 

其二特点是一日游服务器是一个个单独的世界。每个服务器的帐号是独的,每令服务器用户之状态都是未一样的,一个服就是是一个社会风气,大家各部牵扯。

 

新生玩玩家呼吁若跨服打架,于是起了跨服战,再长随着游戏之运行,单个服务器的嬉戏活跃玩家越来越少,所以后期就有矣服务器的汇合和搬迁,慢慢的为服务器的绽开、合并形成了一如既往效仿成熟的营业手段。目前多数娱乐还运用分服的布局来架设服务器,多数页游还是使用这种模式。

 

线程调度

分服虽然足解决服务器扩展的瓶颈,但单台服务器在原先单线程的方式来运作,没道充分利用服务器资源,于是又演变产生了以下2种线程模型。

异步-多线程,基于每个现象(或者房间),分配一个线程。每个场景的玩家与属一个线程。游戏的光景是一贯的,不会见过多,如此线程的数据得以保证不见面持续叠加。每个场景线程,同样应用tick轮询的措施,来定时更新该场景内的(对象状态,刷新地图,刷新NPC)数据状态。玩家如若跨越场景吧,就使投递和通告之方法,告知两独情景线程,以此更新两独情景的玩家数据。

 

多进程。由于单独上前程架构下,总会在承载量的顶峰,越是繁复的娱乐,其独进程承载量就更为小,因此一定要突破进程的克,才能够支持更扑朔迷离的玩。多进程系统的外部分益处:能够使用上多核CPU能力、更易开展容灾处理。

 

大多进程系统于经典的模子是“三层架构”,比如,基于前的观线程再举行改进,把网络有和数据库有分离也单身的过程来处理,逻辑进程专心处理逻辑任务,不合IO打交道,网络IO和磁盘IO分别至由网路进程和DB进程处理。

 

 

3、第三替代网游服务器

前的网游服务器都是分区分服,玩家都吃划分在不同的服务器上,每令服务器运行的逻辑相同,玩家不克在不同服务器之间交互。想要双重多之玩家当平世界,保持玩家的龙腾虎跃度,于是便有矣世界服模型了。世界服类型也生以下3栽演化:

 

 

相同品种(三叠架构)

网关部分分离成单端的gate服务器,DB部分分离为DB服务器,把网络功能独立提取出来,让用户统一去老是一个网关服务器,再出网关服务器转发数及后端游戏服务器。而游戏服务器之间数据交换也合并连接受网管进行置换。所有有DB交互的,都接连到DB服务器来代劳处理。

 

王者荣耀 7

 

二类型(cluster)

 

发矣扳平项目的经验,后续肯定是拆分的更细,性能进一步好,就类似现在微服务,每个相同的模块分布到平等贵服务器处理,多组服务器集群共构成一个游戏服务端。

 

相似地,我们可以一个组内的服务器简单地分为两近乎:场景相关的(如:行走、战斗等)以及气象不系的(如:公会聊天、不吃区域限的交易等)。经常得看的如出一辙栽方案是:gate服务器、场景服务器、非场景服务器、聊天管理器、AI服务器和数据库代理服务器。如下模型:

王者荣耀 8

 

上述遭到我们简要的讲下服务器的老三种档次功能:

气象服务器:它当好至关重要的游戏逻辑,这些逻辑包括:角色当游玩场景中之进入及脱离、角色的行和跑步、角色战斗(包括打怪)、任务之收养等。场景服务器设计的上下是整整娱乐世界服务器性能差异的要体现,它的筹划难度不仅仅在通信模型方面,更主要的是全服务器的系架构和同步机制的设计。

 

切莫场景服务器:它根本担负好和戏场景不相干的娱乐逻辑,这些逻辑不靠游戏之地形图网啊会正常进行,比如公会聊天或世界聊天,之所以将它们由景服务器遭受独出来,是以节约场景服务器的CPU和带富资源,让场景服务器会尽可能快地拍卖那些针对游戏流畅性影响比生之游玩逻辑。

 

网关服务器:
在档次一栽之架中,玩家在多独地图跳转或者场景切换的时节利用跳转的模式,以此进行跳转不同的服务器。还有雷同种植办法是将这些服务器的节点都经网关服务器管理,玩家与网关服务器交互,每个现象或者服务器切换的时,也生网关服务器统一来交换数据,如此玩家操作会比较流畅。

 

经过这种类型服务器架设,因为压力分散了,性能会发强烈提升,负载也还可怜了,包括目前片大型的 MMORPG游戏就是运这架构。不过各增加一级服务器,状态机复杂度可能会见翻倍,导致研发和找bug的成本上升,这个针对开发组挑战比较特别,没有经验,很盛出错。

 

 

三类型(无缝地图)

魔兽世界之丁无缝地图,想必大家记忆深刻,整个世界的倒没有像过去之玩一样,在切换场景的时用loading等待,而是直接行动过去,体验流畅。

 

现的游戏世界图下无缝地图多数应用的是9宫格的体来拍卖,由于地图没有魔兽世纪那么稀,所以用单台服务器多进程处理即可,不过类似魔兽世界这种大世界地图,必须考虑2只问题:

1、多个地图节点如何无缝拼接,特别是地方图节点比较多之时段,如何保证无缝拼接

2、如何支撑动态分布,有些区域人大半,有些区域人不见,保证服务器资源利用的最大化

 

为缓解者问题,比较以往随地图来切割游戏而言,无缝世界并无设有一样块地图上面的人数有还只有由同样玉服务器处理了,此时用一致组服务器来拍卖,每令
Node服务器用来治本均等块地图区域,由
NodeMaster(NM)来吗他们提供整体管理。更胜层次之
World则提供大陆级别的管住服务。

 

王者荣耀 9

一个
Node所负责的区域,地理上没有必要连接于协同,可以合交由一个Node去管理,而这些章在地理及并不曾沟通在一齐的必要性。一个
Node到底管理哪些区块,可以因游戏实时运行的负荷情况,定时维护的上进行更改
NodeMaster 上面的布局。

 

靶的无缝迁移

王者荣耀 10

玩家A、B、C分别表示3种不同之状态,以及不同之动迁方式,我们分别来拘禁。

玩家A: 玩家A以node1地图服务器上,由node1控制,如果搬迁至node2上,需要拿其数额复制到node2上,然后打node1移除。

 

玩家B:
玩家B在node1和node2中间,此时出于node1和node2维护,若是自node1行走到node2的进程被,会于1请求,同时为2请求,待一切运动过去了更移除。

 

玩家C:玩家C在node2地图服务器上,由node2控制,如果搬迁至node1上,需要用那数量复制到node1上,然后起node2移除。

 

切切实实魔兽世界服务器的分析,篇幅过多,我们之后还聊。

 

3、房间服务器(游戏大厅)

屋子类玩法以及MMORPG有充分充分之不同,在于那当线广播单元的不确定性以及播放数量特别有些。而且用相当同令间服务器被个别口上一个服务器。

 

即时同一看似游戏最要之是那个“游戏大厅”的承载量,每个“游戏房间”受逻辑所限,需要保障与播音的玩家数据是个别的,但是“游戏大厅”需要保障一定高之在线用户数,所以一般的话,这种游戏或者要举行“分服”的。典型的玩乐就是是《英雄联盟》这无异于像样娱乐了。而“游戏大厅”里面最有挑战性的天职,就是“自动匹配”玩家进入一个“游戏房间”,这得对具有在线娱乐下举行搜索与过滤。

 

玩家先登录“大厅服务器”,然后选取组队打之作用,服务器会打招呼参与的具备戏客户端,新开端平长达连接到屋子服务器上,这样具有与的用户就可知以房间服务器里进行游玩互动了。

王者荣耀 11

上述就是现阶段娱服务器的演化过程,由于所涉及的情节极多,关于服务器的系网IO以及内存模型都未曾介绍,以后来会又具体说出口这同一局部。

 

近些年文章:从《王者荣耀》来聊聊游戏的轴同步

           
  譬如说《王者荣耀》一种红过

end

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website