python告诉你ti8 dota2英雄bp

文章链接:https://mp.weixin.qq.com/s/phJzZEQojndY-iNe77RF_w

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

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

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

python itchat 爬取微信好友信息

python爬虫学习:爬虫QQ说说并生成词云图,回忆满满

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

再仔细一看,原来这些数据是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 = 1
while 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"]项排序,得到的是元祖的list
new_b_dict = sorted(b_dict.items(), key=lambda x: x[1]["count"], reverse=True)

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

# 创建excel表格
file = xlsxwriter.Workbook("dota.xlsx")
# 创建工作表1
sheet1 = 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地址:https://github.com/taixiang/py_dota

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

欢迎关注我的博客:https://blog.manjiexiang.cn/

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

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

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

原文地址:https://www.cnblogs.com/taixiang/p/9538476.html

时间: 2024-08-02 17:49:22

python告诉你ti8 dota2英雄bp的相关文章

【C#】WinForm 之 DOTA2英雄搭配助手(网页抓取+在线绿色版+源码开放)

睡不着,无聊......再整理点好玩的出来.先上图 效果 碎碎念 自从13级后打出DOTA2的天梯积分以来简直是逆水行舟不进则退啊,室友已经高呼着被游戏玩了!!结果怒删游戏 其实我也发现这游戏不合适我玩…天梯里场场被各种选英雄针对,普通场又是剑圣.斧王横行.加之本人比较懒,不爱看视频,场均10死那是常有的事(打起来跟打WOW战场一样,反正死了有复活:P) 不瞎扯了,其实初衷就是不想被针对(想选个最脏阵容神马的我会告诉你嘛) 核心功能 这里要从Dotamax(http://dotamax.com/

用Python爬取&quot;王者农药&quot;英雄皮肤

0.引言 作为一款现象级游戏,王者荣耀,想必大家都玩过或听过,游戏里中各式各样的英雄,每款皮肤都非常精美,用做电脑壁纸再合适不过了.本篇就来教大家如何使用Python来爬取这些精美的英雄皮肤. 1.环境 操作系统:Windows / Linux Python版本:3.7.2 2.需求分析 我们打开<王者荣耀>官网,找定位到英雄列表的页面 可直接点此链接: https://pvp.qq.com/web201605/herolist.shtml 在这个网页中包含了所有的英雄,头像及英雄名称.点击其

10分钟用Python告诉你两个机器人聊天能聊出什么火花

欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可! 现在不是讲各种各样的人工智能嘛,AI下棋,AI客服,AI玩家--其实我一直很好奇,两个AI碰上会怎样,比如一起下棋,一起打游戏-- 今天做个简单的小实验,看看两个AI一起聊天会是什么样子的.为了让实验效果更好,我们两个机器人选取了不同网站的机器人(图灵和茉莉). 01 准备 1) pip下载安装python的requests模块,这个调用接口发送消息要用到. 2) 去图灵机器人官网(http://www.turingapi.com/)申

Python告诉你今天最冷的地方在哪里

抓取目标 这次我们的目标是爬取全国最冷的 10 座城市. 首先打开目标网站 - 中国天气网. 「 http://www.weather.com.cn/textFC/hb.shtml 」 image 我们要爬取全国所有城市的最低温度,然后获取温度最低的 10 个城市,并绘制成柱状图. 准备工作 由于爬取的数据少,考虑使用「 美味汤 - beautiful soup 」的方式来爬取. 另外,最后需要根据数据生成柱状图,需要安装requests.bs4.html5lib.pandas.matplotl

利用Python爬取OPGG上英雄联盟英雄胜率及选取率信息

一.分析网站内容 本次爬取网站为opgg,网址为:” http://www.op.gg/champion/statistics” ? 由网站界面可以看出,右侧有英雄的详细信息,以Garen为例,胜率为53.84%,选取率为16.99%,常用位置为上单 现对网页源代码进行分析(右键鼠标在菜单中即可找到查看网页源代码).通过查找“53.84%”快速定位Garen所在位置 由代码可看出,英雄名.胜率及选取率都在td标签中,而每一个英雄信息在一个tr标签中,td父标签为tr标签,tr父标签为tbody标

充气娃娃?Python告诉你到底有多爽......

上某东的时候,突然给我弹了一个充气娃娃的广告,于是就点进去就看了一下评论,全是神评论啊.所以我就想着把大神们的评论们扒拉下来仔细瞅瞅,于是这篇文章就诞生了??,纯属学习啊,不要想入非非啊,还有,不喜勿喷! 按照软件设计流程来: 需求分析-功能描述-技术文档-详细设计-编码-测试-交付-验收-后期维护 1.需求分析: 首先我先找了某东最火娃娃,里面评论近乎7万条,这里面神评论一定不少.所以决定从这个里面扒拉我们想要获取的数据 2.功能描述 充气娃娃这种东西,一般大家都在网上见得多,所以玩起来到底感

重学Python - Day 01 - python基础 -&gt; python版本选择+第一个小程序

题外话: Python版本:最新的3.6 安装注意点:勾选添加路径后自定义安装到硬盘的一级目录,例如本人的安装路径: F:\Python 原因:可以自动添加python环境变量,自动关联.py文件,其余的优点很多,例如学习selenium的,使用pip install selenium命令就可以安装selenium 3了,虽然python webdriver的自动化还是2.7居多,但是3.0会是未来 闲言碎语以后再说,现在正式开始学习Python,没办法,不会编程的测试在工作中好吃力,学不会py

mnist的格式说明,以及在python3.x和python 2.x读取mnist数据集的不同

#!/usr/bin/env python # -*- coding: UTF-8 -*- import struct # from bp import * from datetime import datetime # 数据加载器基类 class Loader(object): def __init__(self, path, count): ''' 初始化加载器 path: 数据文件路径 count: 文件中的样本个数 ''' self.path = path self.count = co

Python 3 函数自由变量的大坑

Python中函数是一个对象, 和整数,字符串等对象有很多相似之处,例如可以作为其他函数的参数或返回对象, Python中的函数还可以携带自由变量, 两者无疑极大增进了Python的表达力. 但是Python函数自由变量的内部机制和列表解析或for循环结合使用时却暗藏杀机: #---CASE 1 fs = map(lambda i:(lambda j: i*j),range(6)) print([f(2) for f in fs]) #---CASE 2 fs = [lambda j:i*j f