博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python告诉你ti8 dota2英雄bp
阅读量:5991 次
发布时间:2019-06-20

本文共 5087 字,大约阅读时间需要 16 分钟。

文章链接:

恭喜OG成为ti8冠军,很可惜这次偶数年ti8中国队LGD与冠军失之交臂。

上学那会儿还是个dota的玩家,现在已经不玩了,对于这种国际性的赛事还是会比较关注的,这篇文章就是爬取ti8期间,bp英雄的统计(b是ban的简称:禁止一个英雄上场;p是pick的简称:挑选英雄上场)。

python爬虫之前写过几篇文章的,都是用requests+ BeautifulSoup 进行页面解析获取数据的。

一如既往的,找到这样的页面,但是却解析不到这些数据。

再仔细一看,原来这些数据是js动态加载渲染的,可以看到是接口请求来的数据,庆幸的是这个接口不需要cookie之类的验证信息的,直接get请求可以拿到数据,这样处理起来就方便的,对照页面可以知道json格式的各字段名。

json结构分析

数据来源是接口,直接

response = requests.get(url)data = json.loads(response.text)复制代码

通过json.loads 去解析string类型的数据,主要数据格式如下:

{    total: 402,    data: [{    	match_id: 4080856812,    	radiant: {    		team_id: 15,    		name: "PSG.LGD",    		tag: "PSG.LGD",    		country_code: "CN",    		score: 34,    		bans: [{ //每个英雄数据    			name: "spectre",    			name_cn: "幽鬼",    			id: 67    		}, ...],    		picks: [{    			name: "earthshaker",    			name_cn: "撼地者",    			id: 7    		}, ...]    	},    	dire: {    		team_id: 2586976,    		name: "OG",    		tag: "OG",    		country_code: "US",    		score: 35,    		bans: [{    			name: "tiny",    			name_cn: "小小",    			id: 19    		}, ...],    		picks: [{    			name: "furion",    			name_cn: "先知",    			id: 53    		}, ...]    	},    	radiant_win: 0,    	end_time: "2018-08-26 10:51"    }, ...]}复制代码

每个item含radiant、dire ,其中radiant_win: 1,代表radiant 获胜,0 则代表dire 获胜。bans里面的是ban的英雄数据列表,picks里面是pick的英雄数据列表。

这里是用循环不断去请求获取的,每次的数据是20条,可以改变size改变条数。

page = 1while True:    url = "https://www.dotamore.com/api/v1/league/matchlist?league_id=9870&page=%d&size=20" % page    response = requests.get(url)    data = json.loads(response.text)    page += 1    for item in data["data"]:        # 比赛从8月16开始,小于这个时间生成excel,跳出循环        if item["end_time"] < "018-08-16 00:00":            //生成excel            ...        return        //bp数据        ...复制代码

bp数据

每项里面的bans、picks数据都要处理,每个英雄是一条记录,重复的就+1,所以给每个英雄count 的属性,记录次数。

# item 指radiant 或dire 的bans、picks列表数据def bp(item, bp_dict):    if item is None:        return    # 遍历bans 或picks 数据    for i, bp in enumerate(item):        key = bp["name"]        # 如果这个英雄已存在,count+1        if key in bp_dict.keys():            bp_dict[key]["count"] = bp_dict[key]["count"] + 1        else:  # 不存在就记录一条数据            bp_dict[key] = copy.deepcopy(bp)            bp_dict[key].update(count=1)    return bp_dict复制代码

每条英雄数据是个键值对字典,键是name 属性即英文名字,值就是bans、picks里的各项英雄数据,顺便加上了count 属性。每个英雄数据存在dict()

{ //每条英雄数据    name: "tiny",    name_cn: "小小",    id: 19,    count:1}复制代码

分别获取两只队伍bp数据存放

b_dict = dict()p_dict = dict()# ban的数据bp(item["radiant"]["bans"], b_dict)bp(item["dire"]["bans"], b_dict)# pick的数据bp(item["radiant"]["picks"], p_dict)bp(item["dire"]["picks"], p_dict)复制代码

也可以统计所有英雄的出场次数,非搬即选bp_list。

还可以获取冠军队伍的bp情况,team_id 即队伍的id。

if item["radiant_win"] == 0:    if item["dire"]["team_id"] == "2586976":        bp(item["dire"]["bans"], b_win_dict)        bp(item["dire"]["picks"], p_win_dict)else:    if item["radiant"]["team_id"] == "2586976":        bp(item["radiant"]["bans"], b_win_dict)        bp(item["radiant"]["picks"], p_win_dict)复制代码

生成excel

以上数据我们得到的是字典,里面有各英雄的bp次数,现在要对这些数据进行排序,按次数从大到小排序,这里就用到sorted()方法

# x[0]是根据键排序,x[1]是根据值,这里的值是字典,取["count"]项排序,得到的是元祖的listnew_b_dict = sorted(b_dict.items(), key=lambda x: x[1]["count"], reverse=True)复制代码

得到的是数组,生成表格在之前这篇文章中有过使用,这里使用的是xlsxwriter三方库来操作excel 表格的。

# 创建excel表格file = xlsxwriter.Workbook("dota.xlsx")# 创建工作表1sheet1 = file.add_worksheet("sheet1")# 创建表头headers = ["图片", "英雄", "ban", "", "图片", "英雄", "pick", "", "图片", "英雄", "bp_all"]for i, header in enumerate(headers):    # 第一行为表头    sheet1.write(0, i, header)复制代码

第一行是表头,对应的每一列填充数据

def insert_data(sheet1, headers, bp_list, col1, col2, col3):    for row in range(len(bp_list)):  # 行        # 设置行高        sheet1.set_row(row + 1, 30)        for col in range(len(headers)):  # 列            if col == col1:  # 英雄图片,根据id获取                url = "http://cdn.dotamore.com/heros_id_62_35/%d.png" % bp_list[row][1]["id"]                image_data = BytesIO(urlopen(url).read())                sheet1.insert_image(row + 1, col, url, {
"image_data": image_data}) if col == col2: # 英雄名 name = bp_list[row][1]["name_cn"] sheet1.write(row + 1, col, name) if col == col3: # 统计次数 count = bp_list[row][1]["count"] sheet1.write(row + 1, col, count)复制代码

excel 表格生成,还可以插入柱状图。

def insert_chart(file, sheet1, bp_list, name, M, col_x, col_y):    chart = file.add_chart({
"type": "column"}) # 柱状图 chart.add_series({ "categories": ["sheet1", 1, col_x, len(bp_list), col_x], # 图表类别标签范围,x轴,这里取英雄的名字,即英雄名字那一列,行数根据数据列表确定 "values": ["sheet1", 1, col_y, len(bp_list), col_y], # 图表数据范围,y轴,即次数那一列,行数根据数据列表确定 "data_labels": {
"value": True}, }) chart.set_title({
"name": name}) # 图表标题 chart.set_size({
"width": 2000, "height": 400}) chart.set_x_axis({
'name': '英雄'}) # x轴描述 chart.set_y_axis({
'name': '次数'}) # y轴描述 chart.set_style(3) # 直方图类型 sheet1.insert_chart(M, chart) # 在表格M处插入柱状图复制代码

效果图:

这里只是简单的对数据进行筛选展示,这些数据还是可以用来做更多的数据分析的,数据来源:刀魔数据。

github地址:

最后放上lgd的图片,希望他们明年能在ti9上再干回来

欢迎关注我的博客:

更多精彩欢迎关注微信号:春风十里不如认识你

有个「佛系码农圈」,欢迎大家加入畅聊,开心就好!

过期了,可加我微信 tx467220125 拉你入群。

转载地址:http://buxlx.baihongyu.com/

你可能感兴趣的文章
轻量级ORM
查看>>
C# winform 捕获全局异常
查看>>
追求代码质量: 监视圈复杂度
查看>>
项目管理生命周期各个阶段的文档
查看>>
注册团队博客地址
查看>>
寒假挑战PythonTip(一人一python)总结——算法是程序的灵魂,程序员的心法
查看>>
POJ1816:Wild Words——题解
查看>>
【总结整理】JQuery基础学习---DOM篇
查看>>
Tiles Framework
查看>>
实现事件来回切换
查看>>
PHP基础面试题(1-10)
查看>>
点分治
查看>>
ElasticSearch之Centos7下安装
查看>>
Bootstrap3 表格-带边框的表格
查看>>
Python3 easyinstall error
查看>>
数据库中大的事物
查看>>
基于SOA架构---ServiceProxy定义
查看>>
CodeIgniter开发实际案例-新闻网站【转】
查看>>
WP7->网络->读取网页源码
查看>>
兵以诈立——我读孙子
查看>>