前言
- 抓取的重點是找到每個英雄對應的id編號
分析
-
先觀察單個英雄的單張皮膚圖片的url(如下圖馬超的兩張皮膚圖片所示)
馬超一共有三個皮膚(經(jīng)典算第一張)初烘, 每張皮膚的url分別是
第一張:
https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/518/518-bigskin-1.jpg
第二張:
https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/518/518-bigskin-2.jpg
第三張:
https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/518/518-bigskin-3.jpg從三個url中不難發(fā)現(xiàn),url只有后面的數(shù)字不同(1.jpg厦章、2.jpg考传、3.jpg)
最大為3远荠,因為這里用的例子是馬超(他只有三個皮膚,3對應的是最新的皮膚,以此類推)
假設一個英雄皮膚圖片有n張棚愤,那么此皮膚圖片的url結尾則是 1至n .jpg
n就是皮膚編號
下面再來看看其他英雄(這次我們找的是猴子)
猴子一共有7個圖片
[圖片上傳失敗...(image-4d5711-1609587925338)]-
看一下大圣娶親的url,結尾是7.jpg
與之前的馬超規(guī)律一樣
但有一點不同(都以第一張圖片為例杂数,看我加粗的518跟167)
馬超的第一張url是
https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/518/518-bigskin-1.jpg猴子的第一張url是
https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/167/167-bigskin-1.jpg馬超對應的是 518
猴子對應的是 167
通過以上分析可以推斷出每個英雄都有對應的id編號宛畦,id編號跟皮膚編號結合就可以構成單張的皮膚圖片url
接下來找英雄對應的id編號
- 訪問王者榮耀官網(wǎng)
- 檢查元素
- 全局搜索
[圖片上傳失敗...(image-3cd6e5-1609587925338)]
所有英雄對應的id編號的url鏈接(也包含艾琳)
請求這個url然后解析響應數(shù)據(jù),就可以得到所有的英雄對應的id編號
代碼
import requests
import re
import json
import os
import time
# 獲取當前時間戳揍移,用于計算爬蟲爬取完畢消耗了多少時間
now = lambda: time.time()
# 請求頭
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
"Cookie": "pgv_pvid=120529985; pgv_pvi=8147644416; RK=iSx1Z7fSHW; ptcz=d094d0d03f513f6762a4c18a13ddae168782ec153f43b16b604723b27069d0a7; luin=o0894028891; lskey=000100008bc32936da345e2a5268733bf022b5be1613bd2600c10ad315c7559ff138e170f30e0dcd6a325a38; tvfe_boss_uuid=8f47030b9d8237f7; o_cookie=894028891; LW_sid=s116T01788a5f6T2U8I0j4F1K8; LW_uid=Z1q620M7a8E5G6b2m8p0R4U280; eas_sid=m1j6R057x88566P2Z8k074T2N7; eas_entry=https%3A%2F%2Fcn.bing.com%2F; pgv_si=s8425377792; PTTuserFirstTime=1607817600000; isHostDate=18609; isOsSysDate=18609; PTTosSysFirstTime=1607817600000; isOsDate=18609; PTTosFirstTime=1607817600000; pgv_info=ssid=s5339727114; ts_refer=cn.bing.com/; ts_uid=120529985; weekloop=0-0-0-51; ieg_ingame_userid=Qh3nEjEJwxHvg8utb4rT2AJKkM0fsWng; pvpqqcomrouteLine=index_herolist_herolist_herodetail_herodetail_herodetail_herodetail; ts_last=pvp.qq.com/web201605/herolist.shtml; PTTDate=1607856398243",
"referer": "https://pvp.qq.com/"
}
# 解析函數(shù)次和,返回文本或者二進制或者None
def parse_url(url, get_b=False):
try:
response = requests.get(url, headers=headers)
response.encoding = "gbk"
assert response.status_code == 200
if get_b == True:
return response.content
else:
return response.text
except:
print("status_code != 200(from parse_url)")
return None
# 處理單個英雄
def parse_hero_detail(id, name):
# 保存所有皮膚圖片的本地路徑
path = f"./英雄皮膚/{name}"
if not os.path.exists(path):
os.makedirs(path, exist_ok=True)
# 因為不確定每個英雄有多少個皮膚,所以假設單個英雄一共請求10張皮膚那伐,這樣就不會出現(xiàn)皮膚缺少的情況
for num in range(1, 11):
# 單個英雄皮膚圖片的url鏈接
api_url = f"https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/{id}/{id}-bigskin-{num}.jpg"
# 如果返回None踏施,則說明狀態(tài)碼不是200,即沒有這個請求的皮膚
b_data = parse_url(api_url, get_b=True)
if b_data == None:
print(f"{name} 一共有{num - 1}個皮膚")
print("--------------------------------------------------")
# 沒有新的皮膚了罕邀,立即退出循環(huán)
break
img_path = f"{path}/demo{num}.jpg"
if not os.path.exists(img_path):
try:
download_img(img_path, b_data)
except:
return
print(f"{name} 第{num}張皮膚圖片 下載完畢")
# 下載圖片
def download_img(path, b_data):
with open(path, "wb") as f:
f.write(b_data)
def main():
# 含有每個英雄對應的id畅形、英雄名稱的url
api_url = "https://game.gtimg.cn/images/yxzj/web201706/js/heroid.js"
text = parse_url(api_url)
search_result = re.search('var module_exports = ({.*?})', text, re.S)
hero_info_str = search_result.group(1)
hero_info_str = re.sub("'", '"', hero_info_str)
# 包含 所有英雄以及各自對應的id 的字典
hero_info_dict = json.loads(hero_info_str)
for hero in hero_info_dict:
name, id = hero_info_dict[hero], hero
print(name, id)
parse_hero_detail(id, name)
if __name__ == '__main__':
start = now() # 記錄起始時間
main() # 主函數(shù)
print(f"耗時: {now() - start}") # 計算爬蟲執(zhí)行完畢消耗的時間
運行演示
爬蟲運行完畢結果展示(部分)
補充
- 艾琳是空的,你們懂的