从而python的requests第三正模块抓取王者荣耀所有勇于的皮肤

本文使用python的老三着模块requests爬取王者荣耀所有勇于之图纸,并以图片按照每个英雄呢一个目存入文件夹着,方便作桌面壁纸

    
最近攻读中遇见反射机制,可是老师仅仅是轻描淡写的诠释了同等对接,还是好查资料上一下。

脚时具体的代码,已经过python3.6测试,可以成功运行:

Java反射机制是于运作状态被,对于随意一个看似,都能领略是看似的持有属性和法;对于随意一个靶,都能调用它的肆意一个智及性质;这种动态获取之音讯以及动态调用对象的法门的意义称为Java语言的反射机制。

于所设爬取的网页连接可以透过上荣耀官网找到,

一、Class类

    
1、Class是一个接近,一个叙类的类似(也就算是讲述类本身),封装了叙道的Method,描述字段的Filed,描述构造器的Constructor等性能
   
2、对象照镜子后(反射)可以拿走的信息:某个类的数目成员叫、方法及构造器、某个类到底实现了哪接口。
    3、对于每个接近而言,JRE 都也该保存一个免转换的 Class 类型的对象。
        一个 Class 对象涵盖了一定某个类的关于消息。换句话说:任何类似都是Class类的实例对象
    4、Class 对象只能由系统成立目标
    5、一个看似在 JVM 中只有会出一个Class实例

 

  1 # -*- coding: utf-8 -*-
  2 """
  3 Created on Wed Dec 13 13:49:52 2017
  4 
  5 @author:KillerTwo
  6 """
  7 import requests
  8 import os
  9 hero_list_url = 'http://pvp.qq.com/web201605/js/herolist.json'
 10 hero_skin_root_url = 'http://game.gtimg.cnyxzj/img201606/skin/hero-info/'
 11 skin_base_dir = 'C:\\Users\\lwt27\\Pictures\\image\\heroskin\\'
 12 
 13 
 14 def get_ename(hero_json):#传入获取到的python对象,如hero_list_json
 15     '''获取英雄名称对应英雄编号的一个字典,例如{小乔:106,...}'''
 16     cname_ename = {}
 17     for hero in hero_json:
 18         cname_ename[hero['cname']] = hero['ename']
 19     return cname_ename
 20 
 21 def get_skin_name(hero_json): #传入从网页获取到的json转换为python字典的对象
 22     '''获取英雄名称对应的皮肤的所有皮肤名称的字典,例如
 23     {'小乔':'恋之微风|万圣前夜|天鹅之梦|纯白花嫁|缤纷独角兽',...}'''
 24     cname_skin_name = {}
 25     for hero in hero_json:
 26         cname_skin_name[hero['cname']] = hero['skin_name']
 27     return cname_skin_name
 28 
 29 def get_hero_skin_count(cname_skin_name): #传入英雄名称对应皮肤名称的字典
 30     '''获取每个英雄对应的皮肤的个数,例如{'小乔':5,...}'''
 31     cname_skin_count = {} 
 32     for item in cname_skin_name.items():
 33         cname_skin_count[item[0]] = len(item[1].split('|'))
 34     return cname_skin_count
 35 
 36 def get_skin_name_url(skin_base_rul,cname_skin_count,cname_ename):
 37     #传入皮肤根地址和名称对应皮肤数量的字典和名称对应编号的字典
 38     '''返回英雄名称对应的所有皮肤的url地址列表的字典,例如{小乔:[skin_url1,skin_url2],...}'''
 39     cname_url_list = {}
 40     for cname,count in cname_skin_count.items():
 41         #print(cname)
 42         #print(count)
 43         #print(skin_base_rul)
 44         #print(cname_ename[cname])
 45         base_url = skin_base_rul+str(cname_ename[cname])+'/'+str(cname_ename[cname])+'-bigskin-'
 46         #print(base_url)
 47         skin_url_list = [str(base_url)+str(num)+'.jpg' for num in range(1,count+1)]
 48         cname_url_list[cname] = skin_url_list
 49     return cname_url_list
 50 
 51 #print()
 52 d = get_skin_name_url(hero_skin_root_url,get_hero_skin_count(get_skin_name(hero_list_json)),get_ename(hero_list_json))
 53 #print(d)
 54 
 55 def get_cname_skin_name(cname_skin_name):#传入名称对应皮肤名称字符串的字典
 56     cname_skin_name_dict = {}         #返回名称对应【皮肤名称的列表】的字典
 57     for cname,skin_name_list in cname_skin_name.items():
 58         skin_list = [name for name in skin_name_list.split('|')]
 59         cname_skin_name_dict[cname] = skin_list
 60     return cname_skin_name_dict
 61     
 62 #s = get_skin_name(hero_list_json)
 63 #print(s)
 64 #f = get_cname_skin_name(s)
 65 #print(f)
 66 
 67 def get_hero_skin(cname_url_list,cname_skin_name):#传入名称对应【皮肤名称列表】的字典和名称对应皮肤url列表的字典
 68    # """获取每个英雄的图片"""
 69     for cname,skin_url in cname_url_list.items():
 70         
 71         if mkdir(skin_base_dir+cname):#创建指定目录
 72             os.chdir(skin_base_dir+cname)  #进入到创建的目录
 73             
 74             for i in range(len(skin_url)):
 75                 file_name = cname_skin_name[cname][i]+'.jpg'
 76                 r = requests.get(skin_url[i])
 77                 with open(file_name,'wb') as f:
 78                     f.write(r.content)
 79 #创建目录
 80 def mkdir(path):
 81     # 引入模块
 82     import os
 83     # 去除首位空格
 84     path=path.strip()
 85     # 去除尾部 \ 符号
 86     path=path.rstrip("\\")
 87     # 判断路径是否存在
 88     # 存在     True
 89     # 不存在   False
 90     isExists=os.path.exists(path)
 91     # 判断结果
 92     if not isExists:
 93         # 如果不存在则创建目录
 94         # 创建目录操作函数
 95         os.makedirs(path)
 96         print(path+' 创建成功')
 97         return True
 98     else:
 99         # 如果目录存在则不创建,并提示目录已存在
100         print(path+' 目录已存在')
101         return False
102     return 
103 
104 if __name__ == '__main__':
105     
106     hero_list_body = requests.get(hero_list_url) #请求英雄列表
107     hero_list_json = hero_list_body.json()  #将英雄列表的获取的json数据转换为python对象
108 
109     cname_ename = {}       #英雄名称对应英雄编号的字典
110     cname__skin_name = {} #英雄名称对应皮肤名称字符串的字典
111     cname_skin_count = {} #英雄名称对应皮肤数量的字典
112     
113     cname_skin_name_str_list = get_skin_name(hero_list_json)
114     cname_skin_name_list = get_cname_skin_name(cname_skin_name_str_list)
115     cname_skin_count = get_hero_skin_count(cname_skin_name_str_list)
116     cname_ename = get_ename(hero_list_json)
117     cnam_skin_url_list = get_skin_name_url(hero_skin_root_url,cname_skin_count,cname_ename)
118     get_hero_skin(cnam_skin_url_list,cname_skin_name_list)

第二、反射机制

 反射是Java中同样栽强大的家伙,能够使我们蛮便宜的创始灵活的代码,这些代码可以再次运行时装配,无需在组件之间进行源代码链接。

   作用:

  1. 于运作时判断任意一个靶所属之类似;
  2. 以运行时得类的靶子;
  3. 在运转时访问java对象的习性,方法,构造方法等。

   图片 1

 

  反射的特性:

             为什么而就此反射机制?直接创建对象不就是足以了也,这就是涉及到了动态和静态的定义。

静态编译:在编译时规定项目,绑定对象,即经过。

动态编译:运行时规定项目,绑定对象。动态编译最特别限度发挥了java的油滑,体现了多态的利用,有坐降低类之间的藕合性

映机制的独到之处:可以实现动态创建对象与编译,体现出十分怪的油滑(特别是在J2EE的开发被其的灵活性就显现的好显著)。通过反射机制我们可得到接近的各种内容,进行了相反编译。对于JAVA这种事先编译再运行的语言来说,反射机制可以假设代码更加灵活,更加便于实现面向对象。

比喻:一个重型的软件,当次编译后,发布了,都见面以晚期持续的更新为周全方位程序,我们无可能而用户把以前的卸载,再重新安装新的版,假如这样的话,这个软件肯定是没小人口用底。采用静态的话,需要把所有程序还编译一次才方可兑现效益的换代,而动反射机制以来,它就是可不用卸载,只待以运作时才动态的缔造及编译,就得兑现该功能。
想一下,王者荣耀每次发新英雄还是发生新皮肤的时节都见面发出创新,用户以更新的时刻知光是下充斥一个粗之次序包进行安装,而休用重新安装整个上荣耀游戏,这虽是动动态编译的事例。

照机制的老毛病:对性有影响。使用反射基本上是同种植解释操作,我们得告诉JVM,我们期待开啊又它们
满足我们的要求。这仿佛操作总是慢于只一直实施同一之操作。

下是保留抓取到之图纸的文本夹样例:

 

图片 2

其三、Class中贯彻反射机制的好像

java.lang.Class;                

java.lang.reflect.Constructor; 

java.lang.reflect.Field;        

java.lang.reflect.Method;

java.lang.reflect.Modifier;

上述就是是抓取王者荣耀所有勇于皮肤的略示例,上述的代码并没动python多线程执行抓取图片的函数,所以在实行的当儿或要花几分钟的时光,

季、反射机制得到类产生三种艺术

当以反射获取类的靶子,对象的特性,方法,构造方法等之时光都用创造类的类类型

 

 

package com.neuedu.reflect;
/* 
* 项目名称:Java-Reflect 
* @author:wzc
* @date 创建时间:2017年8月28日 下午8:41:29
* @Description:获取类的类类型
* @parameter  
*   */
public class JavaDemo1 {
    public static void main(String[] args) {
        //Food的实例对象如何表示
        Food food1=new Food();

        /*
         * Food这个类也是一个实例对象,Class类的实例对象
         * 任何一个类都是Class的实例对象,三种表示方式
         * 第一种表达方式--->实际上在告诉我们任何一个类都有一个隐含的静态成员class
        */      
        Class class1=Food.class;
        //第二种表示方式,已知该类的对象getClass
        Class class2=food1.getClass();
        /*
         * c1,c2表示了Food类的类类型(class type)
         * 任何类都是class类的实例对象
         * c1 c2都代表了Food的类类型,一个类只可能是Class类的一个实例对象
         */
        System.out.println(class1==class2);
        //第三种表达方式
        Class class3=null;
        try {
        class3=Class.forName("com.neuedu.reflect.Food");
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
        System.out.println(class2==class3);

}
//创建一个Food类
class Food{
    public void print(){
        System.out.println("hello Food");
    }
}

 

尔后当开展改良,添加应用python多线程执行抓取任务。

 五、创建对象

 
获取类的类类型以后我们就算足以使类类型创建该类的对象

 

package com.neuedu.reflect;
/* 
* 项目名称:Java-Reflect 
* @author:wzc
* @date 创建时间:2017年8月28日 下午8:41:29
* @Description:获取类的类类型
* @parameter  
*   */
public class JavaDemo1 {
    public static void main(String[] args) {
        //Food的实例对象如何表示
        Food food1=new Food();

        /*
         * Food这个类也是一个实例对象,Class类的实例对象
         * 任何一个类都是Class的实例对象,三种表示方式
         * 第一种表达方式--->实际上在告诉我们任何一个类都有一个隐含的静态成员class
        */      
        Class class1=Food.class;
        //第二种表示方式,已知该类的对象getClass
        Class class2=food1.getClass();
        /*
         * c1,c2表示了Food类的类类型(class type)
         * 任何类都是class类的实例对象
         * c1 c2都代表了Food的类类型,一个类只可能是Class类的一个实例对象
         */
        System.out.println(class1==class2);
        //第三种表达方式
        Class class3=null;
        try {
            class3=Class.forName("com.neuedu.reflect.Food");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(class2==class3);
        //我们可以通过类的类类型创建类的对象实例
        try {
        Food food2 = (Food) class1.newInstance();
        food2.print();
        } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    }
}
//创建一个Food类
class Food{
    public void print(){
        System.out.println("hello Food");
    }
}

 

 

 六、获取类的系信息:    类名,方法名,方法的回来值类型,方法的参数列表

package com.neuedu.Uttil;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/* 
* 项目名称:Java-Reflect 
* @author:wzc
* @date 创建时间:2017年8月29日 下午1:22:15
* @Description: 1.利用反射打印类的信息
*               2.利用反射打印类的成员变量
*               3.利用反射打印类的构造方法
* @parameter  
*   */
public class Uttil {
    /*
     * 打印类的信息,打印类的返回值类型,类类名,参数列表
     * 
     * */
    public static void PrintClass(Object obj){
        Class  cInt=obj.getClass();
        System.out.println("类的名称:"+cInt.getName());
        /*
         * Method类,方法对象
         * 一个成员方法就是一个Method对象
         * getMethods()方法获取的是所有的public的函数,包括父类继承而来的
         * getDeclaredMethods()获取的是所有该类自己声明的方法,
         * 
         * */
        Method[] ms=cInt.getMethods();
        System.out.println("[类的返回值类型],[类的名称],[类的参数列表]");
        for (int i = 0; i < ms.length; i++) {
            //得到方法的返回值类型的类类型
            Class returnType=ms[i].getReturnType();
            System.out.print(returnType.getName()+" ");
            //得到方法的名称
            System.out.print(ms[i].getName()+"(");
            //获取参数类型
            Class [] paramTypes=ms[i].getParameterTypes();
            for (Class class1 : paramTypes) {
                System.out.print(class1.getName()+",");
            }
            System.out.println(")");
        }
    }

}

 测试一下:

public class JunitTest {

    @Test
    public void test() {
        String string="hello";
        //Uttil.PrintClass(string);

    }

}

 执行结果:

图片 3

 

七、获取类的性

/*
     * 成员变量也是对象
     * java.lang.reflect.Field;
     * Filed类封装了关于成员变量的操作
     * getFields()方法获取的是所有的public的成员变量的信息
     * getDeclaredFields获取的是该类自己声明的成员变量的信息
     * 
     * 
     * */
    public static void printFieldInfo(Object obj) {
        //获取类的成员变量
        Class class1=obj.getClass();
        Field[] fields=class1.getDeclaredFields();
        for (Field field : fields) {
            //得到成员变量的类型的类类型
            //得到成员变量的类型名
            Class fieldType=field.getType();
            String   typeName=fieldType.getName();
            //得到成员变量的名称
            String   fieldName=field.getName();
            System.out.println(typeName+" "+fieldName);
        }
    }

 测试一下:

        @Test
    public void test() {
        Uttil.printFieldInfo(new Integer(1));
    }

 结果:

图片 4

八、获取类的构造方法

  /*
     * 打印对象的构造函数
     * */
    public static void  printConMessage(Object obj){
        Class class1=obj.getClass();
        /*
         * 构造函数也是对象
         * java.lang.Contructor中封装了构造函数的信息
         * getConstructors获取所有的public的构造函数
         * getDeclaredContructors得到所有的构造函数
         * 
         * 
         */
        Constructor[] ct=class1.getConstructors();
        for (Constructor constructor : ct) {
            System.out.print(constructor.getName()+"(");
            //获取构造函数的参数列表--->得到的是参数列表的类类型
            Class[] paramTypes=constructor.getParameterTypes();
            for (Class class2 : paramTypes) {
                System.out.print(class2.getName());
            }
            System.out.println(")");
        }
    }

 测试一下:

   @Test
    public void test() {
        String string="hello";
        Uttil.printConMessage(string);
    }

 结果:

图片 5

九、通过反射来施行对象的点子

package com.neuedu.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/* 
* 项目名称:Java-Reflect 
* @author:wzc
* @date 创建时间:2017年8月29日 下午6:45:21
* @Description:通过反射执行类的方法
* 
* @parameter  
*   */
public class RunMethod {
   public static void main(String[] args) {
       Student student=new Student("张三", 25);
       //1.要获取方法,首先要获取该方法的类类型,
       Class stuClass = student.getClass();
       /*
        * 2.获取方法、名称和参数列表
        * getMethod获取的是public方法
        * getDelcaredMethod自己声明的方法
        */
       try {
        //stuClass.getMethod("getName",new Class[]{})
        //stuClass.getMethod("getName");
         Method m1=stuClass.getMethod("getName", null);
        //3.方法的反射操作-----以前:student.getName();
         //m1.invoke(obj,args..);  //方法的反射操作是用m1对象来进行方法的调用
         //方法如果没有返回值返回null,有返回值返回具体的返回值,并转换成Object
         m1.invoke(student); 
         System.out.println("==============");
         m1=stuClass.getMethod("getAge", null);
         Object object=m1.invoke(student, null);
         System.out.println("==============");
         //m1=stuClass.getMethod("getAge", int.class);
         m1=stuClass.getMethod("getAge", new Class[]{int.class});
         m1.invoke(student, 2);


    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   
}
}
//student类
class Student{
    private String name;
    private int age;

    public Student(){
    }
    public Student(String name,int age){
        this.name=name;
        this.age=age;
    }
    //无参数方法
    public void getName(){
       System.out.println("name:"+name);
    }
    //无参数方法
    public void getAge(){
        System.out.println("age:"+age); 
    }
    //有参数的方法
    public void getAge(int num){
        System.out.println(num+"年前age:"+(age-num));
    }
    public void studentIn(){
        System.out.println("name:"+name+",age:"+age);
    }

}

 今天就是记录有照最基础的论争,之后会于描绘一些反光的利用,只有用了才能够还好之知反射的定义。

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website