逆向爬虫24 JQuery和Ajax
一. 闭包补充
上节内容说到闭包函数通过 return
向外传递信息,其实还有一种不用 return
的方法向外传递信息,在函数内部创建一个window全局变量,将局部变量的值赋值给它,在函数外部就可以获取到它的值了。
function fn(){
let name = "wusir";
console.log(name);
// 窗口对象-> 全局变量(nnnn)
// 创建一个全局变量 -> 在闭包函数中向外界传递一些信息
window.nnnn = name;
}
fn()
console.log(nnnn);
二. JS和HTML交互
2.1 通过事件触发JS代码
在HTML中可以直接在标签上给出一些事件的触发,例如,页面上的一个按钮
<input type="button" value="点我就爱你"/>
我们能够知道此时在页面中会产生一个按钮,但是该按钮无论如何进行点击,都不会触发任何事件,但此时我要告诉你,人家其实触发了,只是你没处理而已,在我们点击该按钮的时候,浏览器其实收集到了点击事件,但是由于我们没有给出任何 发生了点击事件应该做什么
的事情。所以也就没有了反应,我们可以通过onclick
属性,来给点击事件添加上具体要做什么
<input type='button' value="点我就爱你" onclick="fn()" />
看到了吧,多了个onclick
,其含义是,当发生点击事件时,去执行fn(),fn() 是什么?fn就是我们javascript的一个函数.
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function fn(){
alert("臭不要脸")
}
</script>
</head>
<body>
<input type="button" value="点我就爱你" onclick="fn()">
</body>
</html>
有效果了,发现了么,至此,我们成功的实现了,从HTML中调用JS的这条路打通了。
那么在HTML中有多少种事件可以触发呢?非常多…多到令人发指,我们就记住几个就好了,HTML中的事件可以在浏览器 F12 的Sources页面最右边的 Event Listener Breakpoints
里查看到
click 点击事件
focus 获取焦点
blur 失去焦点
submit 提交表单
change 更换选项
scroll 滚动条滚动
mouseover 鼠标滑过
mouseout 鼠标滑出
mousemove 鼠标滑动
上述是第一种绑定事件的方案,可以直接在HTML标签中使用onxxx系列属性来完成事件的绑定,逆向的时候一看就知道按钮绑定了哪个函数,太容易了,因此,同时JS还提供了以下事件绑定方案:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
// 因为html代码是从上往下加载的,如果不用window.onload,会导致js代码执行的之后,btn按钮还没加载出来,导致事件绑定失败
window.onload = function () {
let btn = document.getElementById("btn"); // 通过id的值来获取到页面元素(标签)
btn.addEventListener("click", function () { // 为事件click添加功能
console.log("我被点了!")
})
}
</script>
</head>
<body>
<input type="button" id="btn" value="按钮">
</body>
</html>
现在我希望点下按钮后,改变HTML中的内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
// 因为html代码是从上往下加载的,如果不用window.onload,会导致js代码执行的之后,btn按钮还没加载出来,导致事件绑定失败
window.onload = function () {
let btn = document.getElementById("btn"); // 通过id的值来获取到页面元素(标签)
btn.addEventListener("click", function () { // 为事件click添加功能
// 向div输出一些文字
document.getElementById("mydiv").innerText = "你爱我吗?"
})
}
</script>
</head>
<body>
<input type="button" id="btn" value="按钮">
<div id="mydiv" style="width: 100px; height: 100px; background: pink;"></div>
</body>
</html>
2.2JS实现登录验证
那么,我们现在相当于可以从HTML转到JS中了,并且在JS中可以捕获到HTML中的内容了,此时,对应的表单验证也可以完成了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload = function () {
// 第一种绑定事件的方法
// document.getElementById("btn").addEventListener("click", function () {})
// 第二种绑定时间的方法
document.getElementById("btn").onclick = function () {
// 第一种获取页面元素的方法
let username = document.getElementById("username").value;
let password = document.getElementById("password").value;
// 第二种获取页面元素的方法
// let username = document.form.username.value;
// let password = document.form.password.value;
// 第三种获取页面元素的方法
// let username = document.querySelector("#username").value;
// let password = document.querySelector("#password").value;
let flag = true;
if (!username) {
document.getElementById("username_info").innerText = "用户名不能为空";
flag = false;
}
if (!password) {
document.getElementById("password_info").innerText = "密码不能为空";
flag = false;
}
if (flag) {
document.getElementById("login_form").submit();
}
}
}
</script>
</head>
<body>
<form id="login_form" action="https://www.baidu.com" name="form">
<label for="username">用户名: </label><input type="text" name="username" id="username"><span
id="username_info"></span><br>
<label for="password">密码: </label><input type="text" name="password" id="password"><span
id="password_info"></span><br>
<input type="button" id="btn" value="点我登录">
</form>
</body>
</html>
发现了么,不经意间,我们通过JS可以改变HTML中的内容了。
三. jQuery
jQuery是一个曾经火遍大江南北的一个Javascript的第三方库。jQuery的理念:write less do more,其含义就是让前端程序员从繁琐的js代码中解脱出来,我们来看看是否真的能解脱出来。
关于jQuery的版本:这里有必要说一下,jQuery一共提出过3个大版本,分别是1.x,2.x和3.x。这里注意,虽然目前最新的是3.x,但各个公司都不约而同的选择了1.x,说明jQuery1.x在编程界的地位是非常非常高的,而且从其执行效率,代码兼容性以及代码可靠性上讲,1.x确实做到了极致,所以,我们学习的版本自然也是1.x了,我们选择和腾讯课堂同一个版本,1.9
jQuery的下载,推荐直接去cdn下载即可,他本质就是一个js文件,去哪儿都一样。
cdn网址:https://www.bootcdn.cn/jquery/1.9.1/
cdn下载jquery网址:https://cdn.bootcdn.net/ajax/libs/jquery/1.9.1/jquery.js
只需要把上面这个jquery下载的网址复制到浏览器上,然后保存(ctrl+s)成js文件就可以了
3.1 jQuery初使用
我们用jQuery来完成一个按钮的基本点击效果,当然,得和传统的JS对比一下
需求:实现按钮触发控制台输出的功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="jquery.js"></script>
<script>
// $是jquery标志性的东西
// window.onload = function () { } // 整个页面加载完后才会执行
// 当页面加载的时候(不管图片加载,只要结构加载完了)就开始执行
// $(document).ready(function () {
// console.log("我爱你!");
// })
// 页面加载完毕,直接执行,等同于上面
$(function () {
// 原生js绑定事件的方式,太繁琐了
// document.querySelector("#btn").addEventListener("click", function () {
// console.log("我爱你!");
// })
// jquery的选择器,document.querySelector("#btn")
$("#btn").click(function () { // write less do more
console.log("你信吗?");
})
})
</script>
</head>
<body>
<input type="button" id="btn" value="你爱我吗?">
</body>
</html>
除了$
外,其他东西貌似都挺容易理解的,而且代码简洁,异常舒爽。
$
是什么鬼,在jQuery中,$
可以认为是jQuery最明显的一个标志了,$()
可以把一个普通的js对象转化成jQuery对象,并且在jquery中$的含义就是jQuery。
3.2 jQuery实现登录验证
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="jquery.js"></script>
<script>
$(function () {
$(".btn").click(function () {
// 在下一次点击的时候. 要清理掉上一次点击之后的提示
$(".info").text(""); // 清理掉所有info中的内容
let username = $("#username").val(); // val() 提取value值 //两个功能. 给参数, 往里塞, 不给参数, 就是往出拿
let password = $("#password").val();
let gender = $("input[type='radio']:checked").val();
let city = $("#city").val(); // 可以直接获取到页面上的被选择的option的value值
let flag = true;
if (!username) {
$("#username_info").text("用户名不能为空!"); //两个功能. 给参数, 往里塞, 不给参数, 就是往出拿
flag = false;
}
if (!password) {
$("#password_info").text("密码不能为空!"); //两个功能. 给参数, 往里塞, 不给参数, 就是往出拿
flag = false;
}
if (!gender) {
$("#gender_info").text("必须要选择性别!"); //两个功能. 给参数, 往里塞, 不给参数, 就是往出拿
flag = false;
}
if (!city) {
$("#city_info").text("必须要选择城市!"); //两个功能. 给参数, 往里塞, 不给参数, 就是往出拿
flag = false;
}
if (flag) {
$("#login_form").submit()
} else {
return;
}
})
})
</script>
</head>
<body>
<form id="login_form" action="http://www.baidu.com">
<label for="username">用户名: </label><input type="text" id="username" name="username"><span class="info"
id="username_info"></span><br />
<label for="password">密码: </label><input type="password" id="password" name="password"><span class="info"
id="password_info"></span><br />
<label>性别: </label>
<input type="radio" id="gender_men" name="gender" value="men"><label for="gender_men">男</label>
<input type="radio" id="gender_women" name="gender" value="women"><label for="gender_women">女</label>
<span class="info" id="gender_info"></span>
<br />
<label for="city">城市: </label>
<select id="city" name="city">
<option value="">请选择</option>
<option value="bj">北京</option>
<option value="sh">上海</option>
<option value="gz">广州</option>
<option value="sz">深圳</option>
</select>
<span class="info" id="city_info"></span>
<br />
<input type="button" class="btn" value="登录">
</form>
</body>
</html>
3.3 属性控制
需求:设置一个按钮,一个文本框,和一个div标签,在文本框中填写内容,每次按下按钮后,讲文本框中的内容添加到div中,并换行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="jquery.js"></script>
<script>
$(function () {
$(".btn").click(function () {
let val = $(".myin").val();
// 获取到数据后可以清理风文本框
$(".myin").val("");
// 把原来div中的内容和文本框的内容合并,丢进去
// $(".mydiv").text($(".mydiv").text() + val); // text塞进去的东西都会当成文本处理
$(".mydiv").html($(".mydiv").html() + val + "<br/>"); // html塞进去的东西会当成html来处理
})
})
</script>
</head>
<body>
<input type="button" class="btn" value="点我有惊喜">
<input type="text" class="myin">
<div class="mydiv"></div>
</body>
</html>
需求:获取CSS样式,设置CSS样式,通过点击按钮来更改CSS样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="jquery.js"></script>
<script>
$(function () {
$(".btn").click(function () {
let display = $(".mydiv").css("display"); // 获取某css样式的值
if (display == "none") {
$(".mydiv").css("display", "block"); // 设置某css样式
} else {
$(".mydiv").css("display", "none");
}
})
})
</script>
</head>
<body>
<input type="button" class="btn" value="点我有惊喜">
<input type="text" class="myin">
<div class="mydiv" style="width: 500px; height: 60px; background: pink; display: none;"></div>
</body>
</html>
需求:自定义属性设置和查看
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="jquery.js"></script>
<script>
$(function () {
$(".btn").click(function () {
// attr() html属性设置
$(".myin").attr("abc", "jay"); // 设置属性值
let src = $(".myin").attr("data-src"); // 查看属性值
console.log(src) // heheda
})
})
</script>
</head>
<body>
<input type="button" class="btn" value="点我有惊喜">
<input type="text" class="myin" data-src="heheda">
<div class="mydiv" style="width: 500px; height: 60px; background: pink; display: none;"></div>
</body>
</html>
3.4 遍历器
处理标签列表时会用到的工具 each(function(i, data){})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="jquery.js"></script>
<script>
$(function () {
// let txt = $("ul li").text();
// console.log(txt);
$("ul li").each(function (i, data) { // i就是索引, data就是dom对象
// console.log(this); // 这里默认的this是js里面的dom对象 相当于拿到的是document.getElementById()拿到的东西
// 把dom变成jquery对象
// let txt = $(this).text();
// console.log(txt);
console.log(i);
console.log($(data).text());
})
})
</script>
</head>
<body>
<ul>
<li>冰箱</li>
<li>洗衣机</li>
<li>手电筒</li>
<li>收音机</li>
</ul>
</body>
</html>
四. 发送ajax请求
首先, 我们用Flask创建一个后台服务器(自己做网站了哈)
目录结构:
服务端
from flask import Flask, render_template, request # pip install Flask
app = Flask(__name__)
@app.route("/")
def index():
# 跳转到首页
print("你曾经来过服务器")
name = "alex"
# 数据是在这里渲染后, 返回个客户端的html
return render_template("index.html", name=name)
if __name__ == '__main__':
app.run()
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/js/jquery.js"></script>
</head>
<body>
我就是一个传统的html页面, 我的名字是{{name}}
</body>
4.1 发送get请求
接下来. 我们使用jquery来发送ajax.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/js/jquery.js"></script>
<script>
function setCookie(name, value) {
let Days = 30;
let exp = new Date();
exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();
}
$(function(){
// 可以在js任意位置设置cookie信息
setCookie("name", "i-have-a-dream")
$(".get_btn").click(function(){
$.ajax({
url:"/ajax_get", // 服务器地址: 域名+url
method:'get', // 发送get请求
headers:{ // 添加请求头信息
"token":"mememmememe",
},
data:{ // 传递参数
name:'alex',
_: new Date().getTime()
},
contentType:'application/json;charset=utf8',
beforeSend: function(req){ // 也可以这样添加请求头信息
req.setRequestHeader("tokken", "i-can-do-it-haha");
},
success: function(back){ // 请求成功后. 返回数据了. 要做什么?
console.log(back);
}
});
})
})
</script>
</head>
<body>
我就是一个传统的html页面, 我的名字是{{name}}
<br/>
<input type="button" class="get_btn" value="点我发送get_请求">
<hr/>
<a href="javascript:void(0);" class="post_btn" >点我发送post_请求</a>
</body>
</html>
服务器处理ajax_get请求
@app.route("/ajax_get")
def ajax_get_req():
# 接收cookie中的信息
n = request.cookies.get('name')
if not n:
return "没有cookie就不要来了."
# 接收header中的信息
token = request.headers.get('token')
if not token:
return "没token还想来?"
# Flask接收get请求的参数
name = request.args.get('name')
_ = request.args.get('_')
if name and _:
# 返回json
return {"name":'alex', "id": 10086, "isMen": True}
else:
return "回家去吧"
4.2 发送post请求(json)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/js/jquery.js"></script>
<style>
#mask{
position:fixed;
top:0;
left:0;
right:0;
bottom: 0;
background-color: rgba(0,0,0, .3);
color: #fff;
font-size:30px;
text-align: center;
padding-top:300px;
display:none;
}
</style>
<script>
$(function(){
$(".post_btn").click(function(){
$('#mask').css("display","block");
$("#data_tbody").remove();
$.ajax({
url:'/ajax_post',
method:'post',
data: JSON.stringify({
name:'alex',
id:'10086'
}),
headers: { // 发送json数据. 要换这个头, 否则服务器收不到数据
"Content-Type": "application/json;charset=utf-8"
},
dataType:"text",
success:function(d){
$('#mask').css("display","none"); // 设置不遮罩
let data = JSON.parse(d);
let tbody = $("<tbody id='data_tbody'></tbody>")
data.forEach(function(item){
let tr = `<tr><td>${item.id}</td><td>${item.name}</td><td>${item.age}</td></tr>`;
tbody.append(tr);
});
$('table').append(tbody);
}
})
});
})
</script>
</head>
<body>
我就是一个传统的html页面, 我的名字是{{name}}
<br/>
<input type="button" class="get_btn" value="点我发送get_请求">
<hr/>
<a href="javascript:void(0);" class="post_btn" >点我发送post_请求_加载一个表格试试</a>
<hr/>
<table width="80%" border="1">
<thead>
<tr>
<td>id</td>
<td>name</td>
<td>age</td>
</tr>
</thead>
</table>
<div id="mask"><span>正在加载中......</span></div>
</body>
</html>
python服务器:
from flask import Flask, render_template, request # pip install Flask
import time
import json
app = Flask(__name__)
@app.route("/")
def index():
# 跳转到首页
print("你曾经来过服务器")
name = "alex"
return render_template("index.html", name=name) # 数据是在这里渲染后, 返回个客户端的html
@app.route("/ajax_post", methods=['POST'])
def ajax_get_post():
# time.sleep(3)
# 接收JSON数据
print(request.json)
lst = [
{"id": 1, "name": "张飞", "age": 16},
{"id": 2, "name": "孙斌", "age": 16},
{"id": 3, "name": "樵夫", "age": 16},
{"id": 4, "name": "大佬", "age": 16},
]
return json.dumps(lst)
if __name__ == '__main__':
app.run()