说实在的个人对游戏并没有多大的兴趣,但唯独对暴雪的Diablo系列很有感情,去年年初开始玩Diablo3,断断续续,感觉最麻烦的是选择技能,每次版本更新可能都有更优的build,这对于我这样的业余玩家来说可不是件好事,好在宏伟秘境后有了天梯,借鉴排名在前的高级玩家们build总没错,于是花了点时间写了这个脚本。

脚本只是统计了主动技能、被动技能和传奇宝石的使用情况,理论上统计其它如装备等信息也是一样简单可行的,但Diablo装备的生成机制使得统计这个没有多大意义,相同的装备属性可能各有优劣,难以比较,而且某些装备坑爹的掉率也不是你想要就能有的。

题外话,不得不说Python太适合写这类功能相对简单的脚本了,一个字:快。

# -*- coding: utf-8 -*-

"""

Diablo3 排名前1000玩家英雄使用技能统计

python diablo.py help

python diablo.py [barbarian|crusader|demon-hunter|monk'|witch-doctor|wizard]

默认使用的是亚服的数据,如果需要美服或欧服,更改`_rank_page`和`_api`变量地址即可

Copyright (c) 2015 JinnLynn

Released under the terms of the MIT license.

"""

from __future__ import unicode_literals, print_function, absolute_import

import os

import sys

import urllib2

import json

import re

__version__ = '1.0.0'

__author__ = 'JinnLynn '

__license__ = 'The MIT License'

__copyright__ = 'Copyright 2015 JinnLynn'

# 排名页面

_rank_page = 'http://tw.battle.net/d3/zh/rankings/'

# api

_api = 'http://tw.battle.net/api/d3/'

_api_profile = os.path.join(_api, 'profile')

_api_data = os.path.join(_api, 'data')

_hero_classes = {

'barbarian': '野蠻人', 'crusader': '聖教軍', 'demon-hunter': '狩魔獵人',

'monk': '武僧', 'witch-doctor': '巫醫', 'wizard': '秘術師'}

_retry = 5

_hero_class = ''

_active_skills = {}

_passive_skills = {}

_unique_gems = {}

def _clear_output(msg=''):

sys.stdout.write('\r{:30}'.format(' '))

sys.stdout.write('\r{}'.format(msg))

sys.stdout.flush()

def _process(stated, total):

msg = '英雄数据分析中... {}/{}'.format(stated, total)

_clear_output(msg)

def _get(url, is_json=True):

# print('GET: ', url)

retry = 5 if _retry < 1 else _retry

while retry > 0:

try:

req = urllib2.urlopen(url.encode('utf8'), timeout=10)

return json.load(req) if is_json else req.read()

except KeyboardInterrupt, e:

raise e

except Exception, e:

retry -= 1

# print('retry', retry, e)

# raise e

def _api_url(*args, **kwargs):

slash = kwargs.get('slash', False)

args = [unicode(arg) for arg in args]

url = os.path.join(*args).rstrip('/')

return url + '/' if slash else url

def get_era():

req = urllib2.urlopen(_rank_page)

return req.geturl().split('/')[-2]

def get_rank_page_url(era):

url_part = 'rift-'

if _hero_class == 'demon-hunter':

url_part += 'dh'

elif _hero_class == 'witch-doctor':

url_part += 'wd'

else:

url_part += _hero_class

return os.path.join(_rank_page, 'era', era, url_part)

def fetch_rank_list():

tags = []

try:

_clear_output('获取当前游戏纪元...')

era = get_era()

_clear_output('获取当前排名前1000的玩家...')

url = get_rank_page_url(era)

html = _get(url, is_json=False)

# re parse

lst = re.findall(

r"a href=\"(.*)\" title=.*class=\"icon-profile link-first\">",

html.decode('utf8'),

re.UNICODE)

# BeautifulSoup parse

# import bs4

# soup = bs4.BeautifulSoup(html)

# lst = soup.select('#ladders-table tbody tr .battletag a')['href']

for item in lst:

try:

tags.append(item.split('/')[-2])

except:

pass

except Exception, e:

print('fetch rank list fail. {}'.format(_rank_page))

raise e

return tags

def get_hero(player_tag):

url = _api_url(_api_profile, player_tag, slash=True)

data = _get(url)

hero_selected = None

for hero in data.get('heroes', []):

if hero['class'] != _hero_class:

continue

last_updated = hero_selected['last-updated']

# 最近使用的英雄

if hero_selected is None or last_updated < hero['last-updated']:

hero_selected = hero

if not hero_selected:

raise Exception('{} hero missing.'.format(player_tag))

url = _api_url(_api_profile, player_tag, 'hero', hero_selected['id'])

return _get(url)

# 主动技能符文

def stat_active_skill_rune(skill_slug, rune):

global _active_skills

if not rune:

return

slug = rune.get('slug')

if slug in _active_skills[skill_slug]['rune']:

_active_skills[skill_slug]['rune'][slug]['count'] += 1

else:

_active_skills[skill_slug]['rune'][slug] = {

'count': 1,

'name': rune.get('name')

}

# 主动技能

def stat_active_skill(active):

global _active_skills

slug = active.get('skill', {}).get('slug')

# d3 API 返回的数据中可能存在空的数据

if not slug:

return

if slug in _active_skills:

_active_skills[slug]['count'] += 1

else:

_active_skills[slug] = {

'count': 1,

'name': active.get('skill').get('name'),

'rune': {}

}

stat_active_skill_rune(slug, active.get('rune'))

# 被动技能

def stat_passive_skill(passive):

global _passive_skills

slug = passive.get('skill', {}).get('slug')

# d3 API 返回的数据中可能存在空的数据

if not slug:

return

if slug in _passive_skills:

_passive_skills[slug]['count'] += 1

else:

_passive_skills[slug] = {

'count': 1,

'name': passive.get('skill').get('name')

}

def stat_unique_gem(items):

global _unique_gems

def get_gem(tooltip):

if not tooltip:

return None, None

url = _api_url(_api_data, tooltip)

data = _get(url)

gems = data.get('gems')

if not gems:

return None, None

gem = gems[0].get('item', {})

return gem.get('id'), gem.get('name')

if not items:

return

lst = [items.get(s, {}) for s in ['leftFinger', 'rightFinger', 'neck']]

for tooltip in [d.get('tooltipParams', None) for d in lst]:

id_, name = get_gem(tooltip)

if not id_:

continue

if id_ in _unique_gems:

_unique_gems[id_]['count'] += 1

else:

_unique_gems[id_] = {

'count': 1,

'name': name

}

def stat(hero):

global _active_skills, _passive_skills

map(stat_active_skill, hero.get('skills', {}).get('active', []))

map(stat_passive_skill, hero.get('skills', {}).get('passive', []))

items = hero.get('items', {})

stat_unique_gem(items)

def output(hero_stated, hero_stat_failed):

def sort(data, count=10):

d = sorted(data.items(), key=lambda d: d[1]['count'], reverse=True)

return d if count <= 0 else d[0:count]

_clear_output()

# print('======')

# print(hero_stated, hero_stat_failed)

# print('======')

# pprint(_active_skills)

# print('======')

# pprint(_passive_skills)

# print('======')

# pprint(_unique_gems)

# pprint(_active_skills.items())

# print('======')

print('\n=== RESULT ===\n')

print('统计英雄数\n')

print(' 成功: {} 失败: {}\n'.format(hero_stated, hero_stat_failed))

print('主动技能使用排名: ')

for _, d in sort(_active_skills):

runes = []

for _, r in sort(d.get('rune', {})):

runes.append('{name}[{count}]'.format(**r))

d.update({'rune_rank': ', '.join(runes)})

print(' {name}[{count}]: {rune_rank}'.format(**d))

print()

print('被动技能使用排名: ')

for _, d in sort(_passive_skills):

print(' {name}[{count}]'.format(**d))

print()

print('传奇宝石使用排名: ')

for _, d in sort(_unique_gems):

print(' {name}[{count}]'.format(**d))

print()

def prepare():

global _hero_class

def print_hc():

print('仅支持以下英雄类型, 默认 demon-hunter:\n')

for c, n in _hero_classes.items():

print(c, ':', n)

if len(sys.argv) == 1:

_hero_class = 'demon-hunter'

elif len(sys.argv) > 2:

sys.exit('参数错误')

else:

arg = sys.argv[1]

if arg == 'help':

print_hc()

print('\nTips: 运行中可随时Ctrl+C终止以获得已统计的数据结果')

sys.exit()

elif arg not in _hero_classes:

print_hc()

sys.exit()

else:

_hero_class = arg

def main():

prepare()

print('待分析的英雄类型:', _hero_classes[_hero_class])

hero_stated = 0

hero_stat_failed = 0

try:

tags = fetch_rank_list()

if not tags:

raise Exception('parse battle.net rank page fail.')

except Exception, e:

print('error,', e)

sys.exit()

total = len(tags)

for tag in tags:

try:

hero = get_hero(tag)

if not hero:

raise Exception('no hero data')

stat(hero)

hero_stated += 1

_process(hero_stated, total)

except KeyboardInterrupt:

break

except Exception, e:

# print('Fail: ', tag, e, hero)

hero_stat_failed += 1

output(hero_stated, hero_stat_failed)

if __name__ == '__main__':

main()

python技能排名_Python获取暗黑破坏神3战网前1000命位玩家的英雄技能统计相关推荐

  1. python输出二进制数字_Python获取数字的二进制值

    我们都知道在计算机中所有的信息最终都是以二进制的0和1来表示,而有些算法是通过操作bit位来进行运算的,这就需要我们了解Python中如何去表示二进制,又如何是进行位运算的. 二进制的表示 首先在Py ...

  2. python关键词排名_python实现查询百度关键词排名并截图标注保存

    前言 该程序正常运行所需要的插件为phantomjs,建议下载mac版本,然后将下载的整个文件夹放在和.py文件同一级的目录下,若是window系统的话则修改程序中的 driver指向的插件目录名称 ...

  3. python读取时间_python 获取时间

    1.python获取当前日期①方法1 #!/usr/bin/python # -*- coding: utf-8 -*- import time today=time.strftime('%Y-%m- ...

  4. python 监视图_python获取zabbix监控图

    领导有个需求,希望每天邮件发出当天服务器的监控状态,开始是每天下午快下班的时候打开zabbix截图,每天都这样实在是累,于是写了一段脚本实现自动抓取图片,并组装成html,通过定时邮件发送,实现日报自 ...

  5. python阿里巴巴排名_python使用urllib模块和pyquery实现阿里巴巴排名查询

    python pyquery不能有空格吗 看地方吧 pyquery库是jQuery的Python实现,可以用于解析HTML网页内容,我个人写过的一些抓取网页数据的脚本就是用它来解析html获取数据的. ...

  6. python 取名字_python 获取如何获取类的名称?

    标准库importlib 内置getattr 内置dir 这几个可以帮助你实现想要的需求,这也是项目当中lazyImport很常见的一种方式. 题主可以自己先根据文档尝试怎么写,有空我再写具体怎么实现 ...

  7. python布尔系列_python – 获取pandas布尔系列为True的索引列表

    使用 Boolean Indexing >>> s = pd.Series([True, False, True, True, False, False, False, True]) ...

  8. python生成时间戳_Python 获取时间戳

    import time time_tup = time.localtime(time.time()) print time_tup format_time='%Y-%m-%d_%a_%H-%M-%S' ...

  9. python工作目录_python获取当前工作目录

    在编程中经常需要用到当前脚本的工作目录,以下是python脚本获取当前工作目录的语句.例test.py importinspect dir = inspect.getfile(inspect.curr ...

最新文章

  1. acm java_ACM Java Native SDK 概述
  2. apache 和 nginx 301重定向配置方法
  3. NCMMSC2021喊你开赛!汉语长短视频直播语音关键词竞赛正式启动!
  4. 天玑机器人颈椎_天玑骨科手术机器人亮相机器人大会 误差不到1毫米
  5. codeforce 606A - Magic Spheres
  6. linux开发板 pc 通讯_从51单片机到Linux 开发板运行hello world(教程4)
  7. Linux读写执行权限
  8. ORACLE Dataguard安装
  9. 从char到QChar
  10. 浅析基于微软SQL Server 2012 Parallel Data Warehouse的大数据解决方案
  11. HDOJ1003 MaxSum【逆推】
  12. 艺龙的执着与固执:等待微信
  13. layui时间日期控件laydate设置默认值,并且结束时间大于开始时间
  14. godot引擎学习7
  15. 用VSCode打开带图片的.md文件
  16. ADB调试关闭荣耀手机的系统更新(烦人的推送)
  17. 快速画简笔画网站推荐以及思考
  18. 方维互动直播系统(美女、游戏、会议、在线教育、体育、赛事直播系统)
  19. 杨锦鑫:美元重返95,欧元绝地反扑
  20. JavaScript淘宝秒杀案例

热门文章

  1. C/C++尾插法建立单链表
  2. kafka-eagle工具安装部署
  3. 非常强大的汉字转拼音的类(带音调)
  4. Springboot集成QQ平台互联授权登入应用
  5. 高数【微分中值定理和导数的应用】--猴博士爱讲课
  6. 【最佳实践】企业内网安全解决方案
  7. Windows下怎么用you-get下载视频
  8. 2022最全前端面试题(持续更新)
  9. 通过Python发送excel中的表格和文字给微信群或好友(微信助手)
  10. react前端下载后端返回文件流(文件流下载excel、csv)