发布时间:2024-01-16 18:30
看了大神的这篇CSDN:20行Python代码爬取王者荣耀全英雄皮肤访问量那么高,忍不住想要蹭一下热点,但是蹭归蹭,总得有点货才行,于是我品我细品,发现其代码总体有三点我觉得值得改进的地方:
import os
import requests
url = \'https://pvp.qq.com/web201605/js/herolist.json\'
herolist = requests.get(url) # 获取英雄列表json文件
herolist_json = herolist.json() # 转化为json格式
hero_cnames = list(map(lambda x: x[\'cname\'], herolist_json)) # 提取英雄的名字
hero_enames = list(map(lambda x: x[\'ename\'], herolist_json)) # 提取英雄的编号
skin_name = list(map(lambda x: x.get(\'skin_name\'), herolist_json))
# 下载图片
def downloadPic():
# 创建wzry主文件夹
if not os.path.isdir(\"wzry\"):
os.mkdir(\"wzry\")
os.chdir(\"wzry\")
for (hero_num,hero_ename) in zip(range(len(hero_enames)),hero_enames): #https://blog.csdn.net/jianglianye21/article/details/78280791?utm_source=distribute.pc_relevant.none-task
# 创建英雄子文件夹
if not os.path.isdir(hero_cnames[hero_num]):
os.mkdir(hero_cnames[hero_num])
# 进入创建好的英雄子文件夹
os.chdir(hero_cnames[hero_num])
skins = skin_name[hero_num].split(\'|\')
for skin_num in range(len(skins)+1): # 由于if im.status_code == 200:这步莫名导致skin_num+1,因此这里总数为len(skins)+1
# 拼接url
onehero_link = \'http://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/\' + str(hero_ename) + \'/\' + str(
hero_ename) + \'-bigskin-\' + str(skin_num) + \'.jpg\'
im = requests.get(onehero_link) # 请求url
if im.status_code == 200: # 这句莫名导致skin_num+1,所以下面编号会-1
skin_num -= 1
open(hero_cnames[hero_num] + \'-\' +skins[skin_num] + \'.jpg\', \'wb\').write(im.content) # 写入文件
# 此时还在英雄子文件夹内,所以需要返回上一层路径,即主文件夹下
os.chdir(\"..\")
downloadPic()
后面几节会详细解释。
原文创建路径方法如下:
os.mkdir(\"C:\\\\Users\\\\Administrator\\\\Desktop\\\\wzry\\\\\" + hero_name[i])
这样的绝对路径可扩展性不高,笔者则加入绝对路径,如下:
if not os.path.isdir(\"wzry\"):
os.mkdir(\"wzry\")
os.chdir(\"wzry\")
直接在代码路径下创建wzry文件夹,加入if判断就不会出现文件夹已存在的错误,比如你运行到一半卡了,但是已经生成了一些文件夹,这时候在运行时如果没有这个判断就会出现已存在的错误,这时候不改代码的话你就需要删掉所有文件夹重新运行。
注意这是创建主文件夹,子文件夹则是各个英雄文件夹,后面创建英雄主文件夹后,就开始生成皮肤图片。
# 创建英雄子文件夹
if not os.path.isdir(hero_cnames[hero_num]):
os.mkdir(hero_cnames[hero_num])
# 进入创建好的英雄子文件夹
os.chdir(hero_cnames[hero_num])
生成皮肤图片后,此时还在英雄子文件夹内,所以需要返回上一层路径,即主文件夹下,如下:
os.chdir(\"..\")
首先获得各皮肤名字列表,如下
skin_name = list(map(lambda x: x.get(\'skin_name\'), herolist_json))
注意此时x[(‘skin_name’]要改成x.get(‘skin_name’)这种方法,原因笔者暂时猜测是因为’skin_name’对应的值是\"正义爆轰|地狱岩魂\"这样复杂的形式,中间多了个\"|\"。
所以后面为了给皮肤分别命名,就有如下代码:
skins = skin_name[hero_num].split(\'|\')
它将skin_name按\"|“符号拆成列表,例如拆分后的为\"skins={“正义爆轰”,“地狱岩魂”}”
可以直接对比原代码,这里点出其中几点。首先把变量i换成了易读的代表hero序号的变量hero_num,并且用了多变量for循环以简化代码,如下:
for (hero_num,hero_ename) in zip(range(len(hero_enames)),hero_enames):
另外注意这句请求HTTP: Status Code时会将for循环后移一步,具体原因笔者,暂时不知,因此只做调整不做解释,如下:
for skin_num in range(len(skins)+1): # 由于if im.status_code == 200:这步莫名导致skin_num+1,因此这里总数为len(skins)+1
和
if im.status_code == 200: # 这句莫名导致skin_num+1,所以下面编号会-1
skin_num -= 1