在拉钩学习的笔记(九)函数继承和进阶

1、对象拷贝
    面向对象的特点:封装,继承,多态(抽象)
    // 封装继承函数
    function extend (parent, child) {
        for (var k in parent) {
            // 子级有的属性不需要继承
            if (child){
                continue;
            }
            child[k] = parent[k];
        }
    }
    extend(parent, child);
    对象拷贝:for……in  父对象的属性拷贝给子对象
2、call 方法
    函数本身就是一种对象,就能够有自己的属性和方法
    call 方法本身是一种执行函数的方法,call 方法调用函数的时候,
        有两个功能:1.更改函数内部的 this 的指向;2. 调用函数执行内部代码
        参数: 第一个参数用来指定 this ;第二个及以后就是传的实参
3、借用构造函数继承属性
    直接对父类型的构造函数进行一个普通调用;Person 普通调用过程中,内部的this指向的是 window;可以通过call 方法更改Person 内部的 this   Person.call(this, name, age, sex);
4、构造函数方法的继承
    子类型的原型对象上,需要继承父类型原型对象的方法
    方法一、对象拷贝继承
        for(var k in Person.prototype) {
            // 保留自己的 constructor 不要进行继承
            if(k === "constructor"){
                continue;
            }
            Student.prototype[k] = Person.prototype[k];
        }
    方法二、原型继承:Student.prototype = new Person();Student.prototype.constructor = Student;
5、组合继承:属性再构造函数内部继承,方法通过原型继承
6、函数声明与函数表达式的区别
    函数声明必须有名字
    函数声明会函数提升,在预解析阶段就已创建,声明前后都可以调用
    函数表达式类似于变量赋值
    函数表达式可以没有名字,例如匿名函数
    函数表达式没有函数提升,在执行阶段创建,必须在表达式执行之后才可以调用
7、函数也是对象
    函数本身也是一种对象,可以调用属性和方法
8、函数的调用和默认 this
    1.普通的函数,是通过 给函数命名或者变量名加 () 方式执行;内部的 this 默认指向 window
    2.构造函数,是通过 new 关键字进行调用;内部的 this 指向的是将来创建的实例对象
    3.对象中的方法,是通过对象打点调用函数,然后加小括号;内部的 this 默认指向的是调用的对象自己
    4.事件函数,不需要加特殊符号,只要事件被触发,会自动执行函数;内部的 this指向的是事件源
    5.定时器和延时器中的函数,不需要加特殊符号,只要执行后,在规定的时间自动执行;内部的 this 指向的是 window
9、call、apply、bind
    call 方法
        call() 方法调用一个函数,其具有一个指定的 this 值和分别地提供的参数(参数列表)。
        注意:该方法的作用和apply()方法类似,只有一个区别,就是 call() 方法接受的是若干个参数的列表,而 apply() 方法接受的是一个包含多个参数的数组。
        语法:fun.call(thisArg, arg1, arg2, ...)
        thisArg 在fun函数运行时指定的 this 值;如果指定了 null 或者 undefined 则内部 this 指向 window
        arg1, arg2,...  指定的参数列表
        返回值:就是函数自己的返回值
    apply 方法
        apply() 方法调用一个函数,其具有一个指定的 this 值和分别地提供的参数(参数列表)。
        注意:该方法的作用和call()方法类似,只有一个区别,就是 call() 方法接受的是若干个参数的列表,而 apply() 方法接受的是一个包含多个参数的数组。
        语法:fun.apply(thisArg, [argArray])
        thisArg 在fun函数运行时指定的 this 值;如果指定了 null 或者 undefined 则内部 this 指向 window
        argArray  指定的参数数组
        返回值:就是函数自己的返回值
    bind 方法
        bind() 功能:第一个可以指定函数的 this 值,bind 方法不能执行函数,但是可以传参
        参数:第一个参数,传入一个指定让 this 指向的对象,第二个参数及以后,是函数参数的列表
        返回值:返回一个新的指定了 this 的函数,也可以叫绑定函数
10、函数的其他成员
    arguments        存储的是函数在调用时,传入的所有 实参 组成的一个类数组对象
    arguments.callee 是函数本身,一般直接调用就可以,不需要这个
    fn.caller           函数的调用者,函数在哪个作用域调用, caller 就是谁,如果在全局调用,值就是 null 
    fn.length           指的是形参的个数
    fn.name             函数的名字
11、高阶函数
    函数可以作为参数;函数可以作为返回值
12、什么是闭包
    一个函数和对其周围状态 (lexical environment,语法环境) 的引用捆绑在一起 (或者说函数被引用包围),这样的组合就是闭包 (closure)。 也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
    闭包  函数定义时天生就能记住自己生成的作用域环境和函数自己,将它们形成一个密闭的环境,这就是闭包。不论函数以任何方式在任何地方进行调用,都会回到自己定义时的密闭环境进行执行。
    观察闭包 从广义上来说,定义在全局的函数也是一个闭包,只是我们没办法将这样的函数拿到更外面的作用域进行调用,从而观察闭包的特点; 闭包是天生存在的,不需要额外的结构,但是我们为了方便观察闭包的特点,需要利用一些特殊结构将一个父函数内部的子函数拿到父函数外部进行调用,从而观察闭包的存在
    闭包的用途 可以在函数外部读取函数内部的成员;让函数内部成员始终存活在内存中
    

由于WebMagic是Java语言编写的爬虫框架,因此在爬取拉钩网站之前,需要先了解该网站的反爬虫机制。拉钩网站采用了多种反爬虫策略,如IP限制、UA限制、Cookie限制、滑块验证码等。因此,在爬取拉钩网站时,需要使用代理IP、随机UA、Cookie池等技术来应对反爬虫机制。 以下是使用WebMagic爬取拉钩网站的步骤: 1. 导入WebMagic依赖:在Maven中添加以下依赖: ``` <dependency> <groupId>us.codecraft</groupId> <artifactId>webmagic-core</artifactId> <version>0.7.3</version> </dependency> ``` 2. 创建爬虫类:继承`Spider`类,并重写`process`方法,定义爬取逻辑。在`process`方法中,使用`Page`对象获取页面信息,并使用`Selectable`对象解析页面数据。如下所示: ``` public class LagouSpider extends Spider { private static final String URL_TEMPLATE = "https://www.lagou.com/zhaopin/Java/%d/?filterOption=%d"; private static final String COOKIE = "cookie"; // 替换为自己的Cookie private static final int MAX_PAGE = 30; public LagouSpider(PageProcessor pageProcessor) { super(pageProcessor); } @Override public void process(Page page) { List<Selectable> jobList = page.getHtml().css("div#s_position_list ul.item_con_list li.con_list_item").nodes(); for (Selectable job : jobList) { String jobName = job.css("div.p_top h3").xpath("string(.)").get(); String companyName = job.css("div.company div.company_name a").xpath("string(.)").get(); String salary = job.css("div.p_bot div.li_b_l span").xpath("string(.)").get(); String workLocation = job.css("div.position div.li_b_l").regex(".*?(.*?)").get(); System.out.println("职位名称:" + jobName); System.out.println("公司名称:" + companyName); System.out.println("薪资待遇:" + salary); System.out.println("工作地点:" + workLocation); System.out.println("==========================="); } } public static void main(String[] args) { Spider spider = Spider.create(new LagouPageProcessor()) .addUrl(String.format(URL_TEMPLATE, 1, 3)) .addCookie("Cookie", COOKIE) .thread(5); for (int i = 2; i <= MAX_PAGE; i++) { spider.addUrl(String.format(URL_TEMPLATE, i, 3)); } spider.run(); } } ``` 在上面的代码中,`LagouSpider`继承了`Spider`类,并在`process`方法中解析了职位名称、公司名称、薪资待遇和工作地点等信息。`main`方法中设置了起始URL、Cookie和线程数,并循环添加URL,最后启动爬虫。 3. 创建页面处理器类:继承`PageProcessor`类,并重写`process`方法,定义页面解析逻辑。如下所示: ``` public class LagouPageProcessor implements PageProcessor { private Site site = Site.me() .setRetryTimes(3) .setSleepTime(1000) .setCharset("UTF-8") .addHeader("User-Agent", UserAgentUtil.getRandomUserAgent()); @Override public void process(Page page) { if (page.getUrl().regex("https://www.lagou.com/zhaopin/Java/.*").match()) { page.addTargetRequests(page.getHtml().css("div.pager_container a").nodes() .stream().map(Selectable::links).flatMap(Collection::stream) .map(link -> link + "&filterOption=3").collect(Collectors.toList())); page.addTargetRequests(page.getHtml().css("div#s_position_list ul.item_con_list li.con_list_item div.p_top a").links().all()); } else if (page.getUrl().regex("https://www.lagou.com/jobs/.*").match()) { page.putField("jobName", page.getHtml().css("div.position-head div.name h1").xpath("string(.)").get()); page.putField("companyName", page.getHtml().css("div.company").regex(".*?公司信息</h3>(.*?)</div>").get()); page.putField("salary", page.getHtml().css("div.position-head div.salary").xpath("string(.)").get()); page.putField("workLocation", page.getHtml().css("div.position-head div.job_request p").regex(".*?(.*?).*?(.*?)").get(1)); } } @Override public Site getSite() { return site; } } ``` 在上面的代码中,`LagouPageProcessor`继承了`PageProcessor`类,并在`process`方法中解析了职位名称、公司名称、薪资待遇和工作地点等信息。`getSite`方法中设置了重试次数、睡眠时间、字符集和随机UA。 4. 运行爬虫:在`LagouSpider`类的`main`方法中启动爬虫即可。 需要注意的是,在爬取拉钩网站时,需要使用代理IP、随机UA和Cookie池等技术来应对反爬虫机制。另外,拉钩网站的页面结构比较复杂,需要使用`Selectable`对象进行解析,具体使用方法可以参考WebMagic的官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值