項目源碼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聊天機器人上,代碼就不放了,下面是運行結果
查詢召喚師
查詢戰績