zoukankan      html  css  js  c++  java
  • 20行Python代码爬取王者荣耀全英雄皮肤改进版

    0 写在前面

    看了大神的这篇CSDN:20行Python代码爬取王者荣耀全英雄皮肤访问量那么高,忍不住想要蹭一下热点,但是蹭归蹭,总得有点货才行,于是我品我细品,发现其代码总体有三点我觉得值得改进的地方:

    1. 其创建文件夹的路径为绝对路径,不适合所有个人电脑和系统
    2. 最后写出的每个皮肤名字为序号,常理说来能够命名为“鲁班七号-电玩小子.jpg"这样更为直观
    3. 代码中的一些变量比如i,j影响代码理解,还有一些结构优化
      下面直接贴上我的完整代码,也差不多20多行:
    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()
    

    后面几节会详细解释。

    1 路径问题

    原文创建路径方法如下:

    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("..")
    

    2 皮肤名字

    首先获得各皮肤名字列表,如下

    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={“正义爆轰”,“地狱岩魂”}”

    3 可读性

    可以直接对比原代码,这里点出其中几点。首先把变量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
    
  • 相关阅读:
    http基础知识摘录
    数据库基础常用知识
    2018第18周总结
    pycharm里html注释是{# #}而不是<!-- -->?
    paramiko错误信息:Paramiko error: size mismatch in put
    jmeter的Classpath即类或者jar包的搜索路径设置
    scp、paramiko、rsync复制文件的区别
    maven打包插件maven-shade-plugin简单介绍
    sqlalchemy多表联合查询的左连接、右连接等使用
    如何查看sqlalchemy执行的原始sql语句?
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13281704.html
Copyright © 2011-2022 走看看