项目源码github地址
https://github.com/challeger/spiders
接口
模拟登录:https://www.wegame.com.cn/api/middle/clientapi/auth/login_by_qq
方法:POST 需要数据:
{ "login_info": { "qq_info_type": 3, "uin": "QQ号", "sig": "加密后的密码" # 这个每天都会变,所以在这之前应该还有一个加密的接口,但我没有爬到.. }, "config_params": { "lang_type": 0 }, "mappid": "10001", "mcode": "", "clienttype": "1000005" }
根据召唤师名查找召唤师:https://m.wegame.com.cn/api/mobile/lua/proxy/index/mwg_lol_proxy/query_by_nick
方法:POST 需要数据:
{ "search_nick": "召唤师名" }
返回json数据
根据召唤师id与所在大区id查找最近战绩:https://m.wegame.com.cn/api/mobile/lua/proxy/index/mwg_lol_proxy/get_battle_list
方法:POST 需要数据:
{ "offset": 0, # 偏移量 "limit": 10, # 查询数量 "filter_type": 0, # 查询类型 0:无筛选 1:匹配 2:排位 3:云顶 "totalNum": 0, "game_id": 26, "slol_id": "9KJ3YaGWNx0", # 召唤师id "area_id": 22, # 大区id "isMe": true }
返回json数据
还有很多接口,比如根据对局id查询对局详情,查询召唤师最近使用英雄,召唤师详细资料之类的,不过这些没有用到,如果有需要可以自己去抓..
思路
使用抓包工具+手机模拟器抓取wegame的数据包
通过请求编辑执行功能,得到了两个必须的cookie
在手机上我没有找到登录时的请求..然后去网页版上尝试了以下,在登录时会有一个POST请求
这个请求会设置cookie
而这正是我们需要的cookie,所以爬虫的流程大概就是:请求这个登录接口,让它设置cookie,然后就可以爬取我们想要的数据了.
代码实现
1.模拟登录
sig每天都会变,所以使用时请自行想办法.我的想法是每天定时通过selenium+mimtproxy,在登录时抓取对应的包,然后将数据保存到数据库中.
当然如果读者找到了接口,欢迎分享...
# 用于登录提交的json数据 LOGIN_DATA = { "login_info": { "qq_info_type": 3, "uin": "3436049981", # QQ号 "sig": "@WUZUNHG6p" # 每天都会换 }, "config_params": { "lang_type": 0 }, "mappid": "10001", "mcode": "", "clienttype": "1000005" } # 爬虫模拟请求头 HEADERS = { 'Referer': 'https://www.wegame.com.cn/middle/login/third_callback.html', 'Accept': 'application/json', 'Accept-Encoding': 'application/json, text/plain, gzip', 'User-Agent': 'okhttp/3.11.0', 'Content-Type': 'application/json;charset=UTF-8', } class Spider_WeGame: def __init__(self): # 建立一个会话 self.session = requests.Session() # 设置请求头 self.session.headers = HEADERS def login(self): # 登录请求url login_url = 'https://www.wegame.com.cn/api/middle/clientapi/auth/login_by_qq' # 请求登录 self.session.post(login_url, data=json.dumps(LOGIN_DATA), verify=False) # 判断登录是否成功 if self.session.cookies.get('tgp_ticket', None): self.session.headers.pop('Referer') # 登录时需要用到,登录成功后就不需要了 print('登录成功') return True else: return False
2.按照昵称搜索召唤师
这里用到的LOL_GameArea是我从Wegame的一个js文件找到的,我将需要的数据提取出来放到了config.py文件中
需要的读者请去我的github项目中下载..
class Player: lol_id = None # lol id lol_nick = None # lol昵称 lol_area = None # 所在大区 lol_head = None # 游戏头像 lol_rank = None # rank class Spider_WeGame: ... def search_lol_user(self, nickname, area=None): search_url = 'https://m.wegame.com.cn/api/mobile/lua/proxy/index/mwg_lol_proxy/query_by_nick' # post请求需要的json数据 data = { 'search_nick': nickname } resp = self.session.post(search_url, data=json.dumps(data), verify=False).json()['data']['player_list'] # 判断是否输入了大区 area_key = None # 通过大区名找到大区id if area: foo = [k for k, v in LOL_GameArea.items() if v['name'] == area] try: area_key = int(foo[0]) except IndexError: print('未找到对应大区..请查看是否输入有误') player_list = [] for foo in resp: # 如果输入了大区,则只找对应大区的召唤师 if area_key: if area_key != foo['area_id']: continue player = Player() player.lol_id = foo['slol_id'] # 游戏id player.lol_nick = foo['game_nick'] # 游戏昵称 player.lol_area = foo["area_id"] # 游戏大区 player.lol_rank = foo['rank_title'] # rank player.lol_head = foo['icon_url'] # 游戏头像 player_list.append(player) return player_list
3.根据召唤师id和所在大区查询最近战绩
class Battle: bat_id = None # 对局id bat_mode = None # 对局模式 bat_use_hero = None # 使用英雄 bat_kill = None # 击杀数 bat_death = None # 死亡数 bat_assist = None # 助攻数 bat_desc = None # 对局备注 bat_time = None # 对局时间 bat_score = None # 对局评分 is_win = None # 胜负 class Spider_WeGame: ... def get_player_battle(self, player: Player, filter_type=0, limit=10): """ 查询玩家的最近对局 :param player: 玩家 :param filter_type: 查询类型 0:无筛选 1:匹配 2:排位 3:云顶 :param limit: 查询数量 :return: """ url = 'https://m.wegame.com.cn/api/mobile/lua/proxy/index/mwg_lol_proxy/get_battle_list' # post请求所需数据 data = { "offset": 0, # 偏移量 "limit": limit, # 查询数量 "filter_type": filter_type, # 筛选条件 0:无 1:匹配 2:排位 3:云顶 "totalNum": 0, "game_id": 26, "slol_id": player.lol_id, # 召唤师id "area_id": player.lol_area, # 所在大区 "isMe": True } resp = self.session.post(url, data=json.dumps(data), verify=False).json()['data'] result = [] for battle_list in resp['player_battle_brief_list']: battle = Battle() try: battle.bat_id = battle_list["battle_id"] # 对局id battle.bat_use_hero = LOL_Champion[str(battle_list["champion_id"])] # 使用英雄 battle.bat_mode = battle_list["game_mode_name"] # 对局模式 battle.bat_kill = battle_list['kill_num'] # 击杀数 battle.bat_death = battle_list['death_num'] # 死亡数 battle.bat_assist = battle_list['assist_num'] # 助攻数 battle.bat_time = battle_list['battle_time'] # 对局时间 时间戳格式 battle.bat_desc = battle_list['ext_tag_desc'] # 对局标签 battle.bat_score = battle_list['game_score'] # 对局评分 result.append(battle) except KeyError: pass return result
测试
最终我把项目集成到了QQ聊天机器人上,代码就不放了,下面是运行结果
查询召唤师
查询战绩