逆向爬虫22 Javascript快速入门

逆向爬虫22 Javascript快速入门

一. Javascript的由来

Javascript是一门能够运行在浏览器上的脚本语言,简称JS。首先, Javascript这个名字的由来就很有意思,不少人认为Javascript和Java貌似很像,容易想象成Java的脚本。但其实不然, 两者之间没有任何关系,纯粹是商业碰瓷。

其次,当初为什么要引入Javascript?早先互联网网速没有现在那么快,用户从浏览器上提交表单时,浏览器将数据发送给服务器,服务器对表单内容进行校验,通过后才返回用户想要的数据,如果校验失败,则返回一个错误结果给用户,用户根据错误结果重新提交表单,重复前面的过程。由于早期网速很慢,因此这个过程就特别费时,导致用户体验很差,因此人们想在浏览器这里就对用户提交的表单先进行本地校验,本地校验通过后再通过互联网发送出去,以免用户经过长时间等待后,才被告知自己内容输错了。由此Javascript就被人们发明出来了,Javascript最早就是用来解决上述这个问题的,在浏览器这对用户输入的表单进行校验,通过后才允许浏览器将表单发送出去。

后来Javascript愈发强大,人们用它来控制浏览器运行时的整个工作流程,这也是我们爬虫为什么要学习Javascript的原因。

二. 如何在HTML中引入Javascript

那么既然JS是可以运行在浏览器上的脚本。并且,我们知道本质上,浏览器是执行HTML程序的,那么如何在HTML中引入JS呢?

方案一,直接在

<!-- 第一个.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>周杰伦</title>	<!-- 页面标题 -->
    <!--
        html的注释
    -->
    <script>
        // 单行注释
        /*
            多行注释
        */
        alert("哈哈")   // 一个警告窗口
    </script>
</head>
<body>
    用户展示的内容		<!-- 用户可见内容 -->
</body>
<script src="./第一个.js"></script>
</html>

方案二,将js代码写在js文件中,然后通过

<!-- 第一个.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>周杰伦</title>
    <!-- <script src="第一个.js"></script> -->		<!-- 可以放在body前面 -->
</head>
<body>
    用户展示的内容
</body>
<script src="./第一个.js"></script>	<!-- 也可以放在body后面 -->
</html>
/* 第一个.js */
alert("哈你个头")

由于html是从上往下加载的,因此如果把javascript放在body前面的话,就会先执行javascript中的代码,如果代码中需要对body中的内容进行处理,则网页就会报错,因此这种情况可以把javascript放在body后面。

三. Javascript基本数据类型

JS虽然是一个脚本语言。麻雀虽小,五脏俱全。在js中也是可以像其他编程语言一样,声明变量,条件判断,流程控制等等。我们先看一下JS中的数据类型

在js中主要有这么几种数据类型(基本)

number  数字, 不论是整数还是小数, 数据类型都是number
string  字符串, 这个没啥可聊的. 就是很单纯的字符串
boolean  布尔值, 只有两个, truefalse. 注意不是大写TF. 
object 对象, 这个比较特殊. 你可以理解为所有被new出来的东西都是对象  
undefined 这个表示未定义. 所有没有被定义过的东西默认都是该类型  

在js中声明变量用var来声明

3.1 number类型变量

/* number类型变量 */
var a, b, c;    // 如果一个变量还没有被赋值,此时该变量不应该被使用,否则是很危险的
var d = 10.01;     // 创建一个变量的正确方案
console.log(d); // 调用控制台,并输出 ---> print
console.log(typeof(d))  // 查看数据类型
var e, f = 18;
console.log(typeof(e))	// 类型是undefined
console.log(typeof(f))	// 类型是number

3.2 string类型变量

/* string类型变量 */
var a = "alex"
console.log(typeof(a))

var b = "10086"
console.log(b + 10)     // 如果+左右两端任意数据是字符串,结局就是字符串拼接
console.log(10 + b)     // 如果+左右两端任意数据是字符串,结局就是字符串拼接
console.log(5 + 5)

var c = parseInt(b)     // int(b) 将字符串转换成数字(整数),parseFloat()
console.log(c + 5)

d = 10086
// 方案一,官方
f = d.toString()		// 数字转字符串
// 方案二,野路子
f = d + ""				// 数字转字符串
console.log(d + 1)
console.log(typeof(f))
console.log(f)

3.3 boolean类型变量

/* boolean类型变量 */
var a = 3 < 2;
console.log(a);      // true, false

// 坑
// and, or, not
// &&,  ||, !
console.log((3>2) && (1<5));
// 等于比较
a = "10086";
b = 10086;
console.log(a == b);    // == 表示判断两端的值
console.log(a === b);   // === 表示判断两端的值,同时还要判断数据类型

// 三元表达式
// a if a > b else b  ---> python的
a = 10;
b = 20;
c = a > b ? a : b   // 表达式1 ? 结果1 : 结果2
console.log(c)

3.4 object类型变量

/* object类型变量 */
var arr = new Array()
console.log(typeof(arr))

3.5 自增自减表达式

var i = 10;
i ++;       // 让i自增1 i += 1
++ i;       // 让i自增1 i += 1
console.log(i)

i --;       // 让i自减1 i -= 1
-- i;       // 让i自减1 i -= 1
console.log(i)

var j = i ++;       // i++表达式的结果是i自增前的值
console.log(i)      // 11
console.log(j)      // 10

var j = ++ i;       // ++i表达式的结果是i自增后的值
console.log(i)      // 11
console.log(j)      // 11

var i = i ++;       // 任何编程语言的赋值符号的优先级都是最低的
console.log(i)      // 10

3.6 字符串操作

s.split()  字符串切割
s.substr(start, len)  字符串切割, 从start开始切, 切len个字符
s.substring(start, end)  字符串切割, 从start切割到end
s.length  字符串长度
s.charAt(i) 第i索引位置的字符
s.indexOf('xxx')  返回xxx的索引位置, 如果没有xxx. 则返回-1
s.includes("xxx") 判断xxx是否出现在s中. 
s.toUpperCase() 转换成大写字母
s.startsWith("xxx")  判断是否以xxx开头
var s = "alex_wusir_sb"
// 切割
console.log(s.split("_"))
console.log(s.substr(3, 4))     // substr(start, len)
console.log(s.substring(3, 4))  // s[3:4] substring(start, end)
console.log(s.length)       // len(s)
console.log(s.charAt(3))    // s[3]
console.log(s.indexOf("wusirdebaba"))   // 如果返回的是-1没有,如果不是-1,就有
console.log(s.includes("wusirdebaba"))  // 判断xxx是否存在,用得少
console.log(s.startsWith("alexdebaba"))

四. JS条件分支

除了HTML以外,几乎所有的编程语言都有条件判断的功能。比如,python,我们用if语句来做条件判断。到了javascript中也是一样的,也使用javascript来做条件上的判断。

4.1 if条件

// 语法
if(条件1){
    代码块1    
}
// 解读: 当`条件1`成立时, 执行代`码块1`中的内容, 如果`条件1`不成立. 则不执行该`代码块1`中的内容
// 注, 如果代`码块1`中的内容只有一行. 则可以省略外面的大括号(一些逆向工程里会有)
// 语法
if(条件1){
    代码块1
} else {
    代码块2
}
// 解读: 当`条件1`成立时, 执行`代码块1`中的内容, 如果`条件1`不成立. 则执行`代码块2`中的内容
// 语法
if(条件1){
    代码块1
} else if(条件2) {
    代码块2
} else if(条件3) {
    代码块3
} ... {
	代码块n
} else {
    代码块else
}
// 解读: 当`条件1`成立时, 执行`代码块1`中的内容, 如果`条件2`不成立. 则执行`代码块2`中的内容...如果都不成立, 最终执行`代码块else`中的内容. 

4.2 switch - case条件

switch语句,该语句是python中不存在的,但是在Java和C,以及JS中依然会有使用

switch(变量){
    case1:
        代码块1
        break  // 可选
    case2:
      	代码块2
        break  // 可选
    case3:
        代码块3
        break  // 可选
        
    default:   // 可选
        default代码块
}
/*
	解读: 
		执行时, 
		switch会判断变量的值是否是`值1`, 
		如果是, 则执行代码块1以及代码块1中的break, 
		如果不是, 则继续判断`值2`...
		如果前面的`值`都没有和`变量`相等的.则执行`default代码块`. 
	注意, 
		每一个`case`中都可以选择`break`, 也可以不选择`break`, 需要注意的是, 如果不写`break`. 
		那么就会形成`case穿透`现象. 
	例, `变量`的值如果和`值1` 相等. 并且case1中没有写`break`, 
	则在执行的时候. 会执行完`case1`中的代码. 
	然后会自动穿透到`case2`中去执行里面的代码, 而不经过case2中的数据的验证. 
*/

五. JS中的循环语句

5.1 while循环

在js中有三种循环语句,首先是while循环。它的逻辑和咱们python中的while几乎一模一样,就是符号上有些许的区别。

// 语法
while (条件) {
    循环体 ->  里面可以有breakcontinue等关键字
}
/*
	判断`条件`是否为真, 如果`真`, 则执行`循环体`.执行完`循环体`, 会再次判断`条件`....
	并且在循环中也可以使用`break`和`continue`等关键字来控制循环的走向. 
*/

5.2 do - while循环

// 语法
do{
    循环体
} while(条件);
/*
	解读:
		先执行`循环体`, 然后判断`条件`是否成立, 如果成立.在来一次. 
	注意, 由于do..while是先执行的`循环体`. 所以, 不论条件如何, 至少执行一次`循环体`
*/

5.3 for循环 (两种方式)

// 语法: for的第一种语法
for(表达式1; 表达式2; 表达式3){
	循环体
}
/*
	解读: 
		for循环和我们python中的循环是完全不一样的. 解读起来会有点儿麻烦. 
		首先, 在执行的时候, 先执行`表达式1`, 
		然后, 判断`表达式2`得到的结果是否真, 如果`真`, 则执行循环体, 
		再然后, 执行`表达式3`, 
		再然后, 判断`表达式2`执行的结果是否为`真`, 如果`真`, 则执行`循环体`
        再然后, 执行`表达式3`
        .....
        直到, `表达式2`得到的结果是`假`, 则跳出循环
*/
// 看起来很绕. 我们用for循环来跑一个1~99
for(var i = 1; i < 100; i++){
    console.log(i);
}
/*
	首先, i = 1, 
	然后, 判断 i < 100 成立
		打印i
	在然后, i++, i变成2
	再然后, 判断 i < 100 还是成立
		打印i
	再然后, i++, i变成3
	再然后, 判断 i< 100 还是成立
		打印3....
	....
	当i = 100了. i < 100不成立. 程序结束 
*/

// for循环的固定逻辑也就这样了
for(变量声明; 条件判断; 改变变量){
 	循环体
}
// for的第二种用法
var a = [11,22,33,44,55,66]
for(let i in a){
    console.log(i + "_" + a[i])
}
// 这种写法非常类似python中的for循环. 但是要注意. 这里的`i`拿到的仅仅是 `数组a`的索引信息. 
// 如果需要数据 a[i]

// 列表特有的一个方案
var arr = [11, 22, 33, 44]
arr.forEach(function(item) {  // 让arr中的每一个去执行一次里面的函数. 把被循环的内容一个一个的传递给函数
    console.log(item);
})  // map()  ?????

六. JS中的数组和对象

6.1 数组

在JS中创建数组非常简单,直接[ ]即可。也可以用正规军的new Array(),不过效果都是一样的。

var as = [11,22,33,44,55];
var bs = new Array(11,22,33,44,55)

数组的常用操作

arr.length;  // 数组长度
arr.push(data);  // 添加数据
arr.pop();  // 删除数据

// arr中的每一项循环出来. 分别去调用function函数, 会自动的将`数据`传递给函数的第一个参数
arr.forEach(function(e, i){  // 第二个参数是可选的
    console.log(i+"__"+e);
});
arr.join("连接符");  // 使用`连接符`将arr中的每一项拼接起来. 和python中的 "".join()雷同

6.2 对象

在JS中创建一个对象非常容易,和python中的字典几乎一样{ }

var p = {
    name: "汪峰",
    age: 18,
    wife: "章子怡",
    
    chi: function(){
        console.log("吃饭")
    }
};

使用对象

p.name
p.age
p['wife']
p.chi()
p['chi']()

从上述内容中几乎可以看到,JS对象的使用几乎是没有门槛的,十分灵活

for(var n in p){
    if(typeof(p[n]) != 'function'){
        console.log(p[n])
    }
}

七. JS中的函数(重点)

在JS中声明函数和python差不多,也要有一个关键字顶在前面。python是def,到了JS里换成了function,只不过在JS中没有像python那么死板,必须def后面必须跟上函数名,这也为我们未来做逆向提供了第一个超大的伏笔。

// 语法
// 声明函数
function 函数名(形参1, 形参2, 形参3....){
    函数体
    return 返回值
}
// 调用函数
函数名(实参1, 实参2, 实参3....)
// 除了写法换了一丢丢. 其他的东西和python完全一致,

简单来个案例看看

function an(a, b){
    return a + b
}

ret = an(1, 2)
console.log(ret);  // 3

很简单不是么?那为什么我们在网页上看到一些网站的JS是如此的复杂呢?

注意了,JS其实没有一个非常非常严格的语法规则。只要能够形成 xxx() 并且xxx是一个函数的话就可以执行.

例如:

var an = function(a, b){
    return a + b 
}
an(1, 2)  // an虽然是var声明的, 但是它的指向是一个函数. 那就可以执行

var $ = function(a, b){
    
}
$(1, 2) // $没有被JS使用. 我就可以用啊. _也OK


// 这个也很过分. 这个东东要拆开来看 第一个括号里面放的就是一个函数啊. 所以依然可以执行. 
(function(a, b){
    return a + b}
)(1, 2)

c = (function(){
    var m = {
        name:'alex',
        age:'18',
        xijiao: function(a){
            console.log(a+"来帮我洗脚");
        }
    }
    return m
})

//  还有最后一个问题. 未来我们也会遇到的. 就是它这个return
var an = function(){
    return console.log("我爱你"), console.log("爱你妹"), "哈哈"
}
// 注意我们发现js会把return后的每一个,都执行一次. 但是最终真正的返回值其实是最后的那个"哈哈"
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值