python简单爬取王者荣耀全英雄皮肤图片
昨天在某公众号看见一篇关于用python爬王者荣耀中所有英雄的皮肤的文章,
https://mp.weixin.qq.com/s/UgF5FYJ5dX1aNw6K0E_Jjw
感觉挺有趣的,下载来当壁纸也不错,就动手一波,环境用的是python3。过程中也遇到了一点问题,所以记录下来

第一步首先打开
http://pvp.qq.com/web201605/herolist.shtml F12分析一波网页结构。。。

通常写这种爬虫,一般都是先分析结构,简单判断下是否有反爬机制。。看下正则表达式怎么写或者使用beatifulsoup的解析器然后再用urllib的套件下载。。。但是在经过数次尝试后发现其中有点坑。。。原因是这个页面有些英雄的链接及图片是通过js加载出来的,源代码里面根本没有。。比如这个新出的英雄司马懿。。。右键直接查看源代码。。发现第一个显示的英雄是狂铁。。(扎心)

后来搜索了一下几位前辈的文章。。发现他们都提到了一个herolist.json。。。于是重新刷新之后在控制台的network找到这个json文件。。。


这个json文件存放的是所有英雄的编号、名字、和皮肤的名字。。。
有了这些。。接下来需要要找到的是所有皮肤图片的地址。。。
点击进入英雄的详情页。。继续F12

多点几个分析。。发现皮肤的图片地址都是类似这种格式
http://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/(英雄编号)/(英雄编号)-bigskin-(第几个皮肤).jpg
而编号和皮肤数都在刚才的json文件中。。。
下面就开始写代码了。。。完整代码如下
#-*- coding:utf-8 -*-import requestsimport jsonimport osimport timestart = time.time() #程序开始时间url=requests.get('http://pvp.qq.com/web201605/js/herolist.json').contentjsonFile=json.loads(url) #提取json#print(jsonFile)x = 0 #用于记录下载的图片张数#目录不存在则创建hero_dir='E:\code\python\skin\\'if not os.path.exists(hero_dir):os.mkdir(hero_dir)for m in range(len(jsonFile)):ename = jsonFile[m]['ename'] #编号cname = jsonFile[m]['cname'] #英雄名字skinName = jsonFile[m]['skin_name'].split('|') #切割皮肤的名字,用于计算每个英雄有多少个皮肤skinNumber = len(skinName)#下载图片,构造图片网址for bigskin in range(1,skinNumber+1):urlPicture = 'http://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/'+str(ename)+'/'+str(ename)+'-bigskin-'+str(bigskin)+'.jpg'picture = requests.get(urlPicture).content #获取图片的二进制信息with open(hero_dir+cname+'-'+skinName[bigskin-1]+'.jpg','wb') as f: # 保存图片f.write(picture)x=x+1print('正在下载....第'+str(x)+'张')end = time.time() #程序结束时间time_second = end-start #执行时间print('共下载'+str(x)+'张,共耗时'+str(time_second)+'秒')
效果:



在这里并没有使用urllib的包。。也没有多线程或者多进程来下载。。而且用urlretrieve有时候很容易出现假死的现象,也有可能是网络问题(手动捂脸)
下面这个是用urlretrieve下载的,为了防止假死的现象,使用了sleep。。也不知行不行。。(再次捂脸)。。也放上来,有需要可以测试下
#-*- coding:utf-8 -*-import urllib.requestimport jsonimport timeimport osstart = time.time()respond = urllib.request.urlopen('http://pvp.qq.com/web201605/js/herolist.json')respond = respond.read().decode('utf-8') #防止出现编码问题respond = respond.encode('utf-8')[3:].decode('utf-8')json_hero = json.loads(respond)hero_num = len(json_hero)hero_dir='E:\code\python\skin\\'if not os.path.exists(hero_dir):os.mkdir(hero_dir)x=0for i in range(hero_num):skin_names = json_hero[i]['skin_name'].split('|')for cnt in range(len(skin_names)):save_file_name = ( hero_dir+ str(json_hero[i]['ename']) + '-' + json_hero[i]['cname'] + '-'+ skin_names[cnt] + '.jpg')skin_url = ('http://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/' + str(json_hero[i]['ename']) + '/'+ str(json_hero[i]['ename']) + '-bigskin-' + str(cnt+1) + '.jpg')urllib.request.urlretrieve(skin_url, save_file_name)time.sleep(1)x+=1print('正在下载...第'+str(x)+'张')end = time.time()time_second = end-startprint('共下载'+str(x)+'张,共耗时'+str(time_second)+'秒')
