爬虫补环境案例---问财网(rpc,jsdom,代理,selenium)
目录
一.环境检测
1. 什么是环境检测
2.案例讲解
二 .吐环境脚本
1. 简介
2. 基础使用方法
3.数据返回
4. 完整代理使用
5. 代理封装
6. 封装所有使用方法
jsdom补环境
1. 环境安装
2. 基本使用
3. 添加参数形式
Selenium补环境
1. 简介
2.实战案例
1. 逆向目标
2. 实现代码
3.实现接口
1.实际使用
RPC
1. RPC 简介
补环境案例
找加密位置
开始补环境
方法1:传统补
方法二-jsdom
方法三----利用selenium补环境
方法四:rpc
一.环境检测
1. 什么是环境检测
- 由于浏览器和node的差别,会导致浏览器的js代码在node没有办法执行,js代码会根据浏览器的这些属性来判断你是不是在真正的浏览器执行的代码,要不是正确的浏览器环境则不会返回正确的数据信息.
- 拿到代码在node里面执行、经常看到这一类型的错误,提示xxx未定义,其实这一块就是浏览器对象的一些特征
if (navigator['userAgent']){^
ReferenceError: navigator is not defined
2.案例讲解
- 检测执行代码是否存在navigator, 可以通过补空的方式
navigator = {}
navigator.userAgent = '11111'
function ps(){if (navigator['userAgent']){return 'hello world'} else {return '失败'}
}
console.log(ps());
- 检测属性长度,会根据长度来判断你的数据是否正确,是不是一个空数据
location = {}
location.href = '123123'
function ps(){if (location['href'].length > 3){return 'hello world'} else {return '失败'}
}
console.log(ps());
- js异常代码捕获,很多情况下可能js代码会把异常给捕获掉导致我们结果不对
- 可以输出异常捕获的内容, 或者可以直接把异常捕获的代码直接删除,把错误暴露出来
location = {}
location.host = '12334'
navigator = {}
navigator.userAgent = '1231234'
function pn() {// try {verify_local()if (navigator['userAgent']) {return 'hello world'}// } catch (e) {// console.log(e)// return '错误的数据'// }
}
function verify_local() {if (location.host.length > 2) {return 'xxx'}
}
console.log(pn());
- 浏览器和node环境差异
- 在 Node.js 中,exports 是一个用于导出模块中的函数、对象、变量等的对象。
- 浏览器是undefined
- 可以删除, 或者可以修改的判断成功
// 浏览器和 node差异
sss = "undefined" != typeof exports ? exports : void 0
console.log(typeof sss);
- global检测
glb= "undefined" == typeof window ? global:window
二 .吐环境脚本
1. 简介
Proxy可以理解为,在目标对象之前设一层"拦截",外界对该对象的访问,都必须通过这层拦截,可以对外界的访问进行过滤和改写(表示可以用它"代理"某些操作,可以翻为“代理器")。
api地址: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Prox
Proxy对象由两个部分组成:target、handler
target:目标对象handler:是一个对象,声明了代理target的指定行为,支持的拦截操作,一共13种:
- get(target,propKey,receiver):拦截对象属性的读取。
- target: 目标对象
- propKey: 被获取的属性名。
- receiver: Proxy 或者继承 Proxy 的对象
- set(target,propKey,value,receiver):拦截对象属性的设置,返回一个布尔值(修改成功)。
- target: 目标对象
- propKey : 被获取的属性名。
- value: 新属性值。
- receiver: Proxy 或者继承 Proxy 的对象
一般的补环境的是通过运行程序后的undefined报错去一点一点分析,一点一点的去补一些环境,是非常掉头发的。
所以我们使用 Proxy 对全局遍历window、document、navigator等常见环境检测点进行代理,拦截代理对象的读取、函数调用等操作,并通过控制台输出,这样的话我们就能够实现检测环境自吐的功能,后续我们再针对吐出来的环境统一的进行补环境,这样就会方便的多。
2. 基础使用方法
var target = {name: 'JACK',age: 18,
};
var p = new Proxy(target, {
get: function (target, propertyKey, receiver) {// 1 原对象// 2 访问属性// 3 代理器处理对象console.log(target, propertyKey, receiver)},set: function(target,propertyKey,value,receiver){// 1. 原对象// 2. 设置的属性// 3. 设置的值// 4. 代理器代理的对象console.log(target, propertyKey, value, receiver)}
})
p.age
p.user = 'aa'
注意:
我们现在写的代码,已经能够去拦截到取值和设置的操作,但是这个代码会打乱代码的后续运行,还并没有把对应的操作作用在原对象上,怎么解决呢?
3.数据返回
Reflect.get(target, propertyKey, receiver); //查找并返回target对象的name属性,receiver绑定this
Reflect.set(target, propertyKey, value, receiver); //设置target对象的name属性等于value
Reflect.set(target, name, value, receiver) 是 JavaScript 中的 Reflect 对象的一个方法。它用于设置指定对象的属性值,并返回一个布尔值,表示设置是否成功。
参数的含义如下:
- target:要设置属性值的目标对象。
- propertyKey:要设置的属性名。
- value:要设置的属性值。
- receiver(可选):设置属性时绑定的 this 值。
4. 完整代理使用
var target = {name: 'JACK',age: 18,
};
var p = new Proxy(target, {
get: function (target, propertyKey, receiver) {temp = Reflect.get(target, propertyKey, receiver); //查找并返回target对象的name属性,receiver绑定this// 1 原对象// 2 访问属性// 3 代理器处理对象// console.log(target, propertyKey, receiver)console.log(`对象${target}--> get了属性--> ${propertyKey} 值是--> ${temp}`);return temp},set: function(target,p,value,receiver){temp = Reflect.set(target, p, value, receiver);// 1. 原对象// 2. 设置的属性// 3. 设置的值// 4. 代理器代理的对象// console.log(target, propertyKey, value, receiver)console.log("set: ", target, p, target[p]);return temp}
})
// console.log(p.age);
p.user = 'aa'
console.log(p.user)
5. 代理封装
// 目标对象(被代理对象)
var target = {name: 'JACK',age: 18,lili:{zs:'nana'}
};
function XlProxy(obj,name){return new Proxy(obj,{get(target, p, receiver) {temp = Reflect.get(target,p,receiver)console.log(`对象${name}--> get了属性--> ${p} 值是--> ${temp}`);if (typeof temp == 'object'){// 对于对象套对象进行挂代理temp = XlProxy(temp,name + '-->' + p)}return temp}})
}
sss = XlProxy(target,'target')
sss.name
sss.lili.zs
6. 封装所有使用方法
// 代理器封装
function get_enviroment(proxy_array) {for(var i=0; i<proxy_array.length; i++){handler = '{\n' +' get: function(target, property, receiver) {\n' +' console.log("方法:", "get ", "对象:", ' +'"' + proxy_array[i] + '" ,' +'" 属性:", property, ' +'" 属性类型:", ' + 'typeof property, ' +// '" 属性值:", ' + 'target[property], ' +'" 属性值类型:", typeof target[property]);\n' +' return target[property];\n' +' },\n' +' set: function(target, property, value, receiver) {\n' +' console.log("方法:", "set ", "对象:", ' +'"' + proxy_array[i] + '" ,' +'" 属性:", property, ' +'" 属性类型:", ' + 'typeof property, ' +// '" 属性值:", ' + 'target[property], ' +'" 属性值类型:", typeof target[property]);\n' +' return Reflect.set(...arguments);\n' +' }\n' +'}'eval('try{\n' + proxy_array[i] + ';\n'+ proxy_array[i] + '=new Proxy(' + proxy_array[i] + ', ' + handler + ')}catch (e) {\n' + proxy_array[i] + '={};\n'+ proxy_array[i] + '=new Proxy(' + proxy_array[i] + ', ' + handler + ')}')}
}
proxy_array = ['window', 'document', 'location', 'navigator', 'history','screen']
get_enviroment(proxy_array)
jsdom补环境
参考地址:Create new page · jsdom/jsdom Wiki · GitHub中文文档
jsdom是一个纯粹由 javascript 实现的一系列 web标准,特别是 WHATWG 组织制定的DOM和 HTML 标准,用于在nodejs中使用。大体上来说,该项目的目标是模拟足够的Web浏览器子集,以便用于测试和挖掘真实世界的Web应用程序
1. 环境安装
npm install jsdom --save
2. 基本使用
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
title = dom.window.document.querySelector("p").textContent
console.log(title)
3. 添加参数形式
const dom = new JSDOM(``, {url: "http://q.10jqka.com.cn/",referrer: "http://q.10jqka.com.cn/",contentType: "text/html",includeNodeLocations: true,storageQuota: 10000000
});
Selenium补环境
1. 简介
Selenium就是一个真实的环境地址,对于我们拿下来的js代码,在node是需要补环境的,但是在浏览器去执行的话,他就是一个真实的浏览器环境,所以可以节省我们扣代码的时间,我们可以把扣下来的代码直接用Selenium来进行访问
2.实战案例
1. 逆向目标
- 网址:A股市场_同花顺行情中心_同花顺财经网
- 参数:cookie :v
2. 实现代码
- 我们把同花顺的js代码直接放到html文件
- python代码
import os
from selenium import webdriver
PRO_DIR = os.path.dirname(os.path.abspath(__file__))
def driver_sig(html_file):option = webdriver.ChromeOptions()option.add_argument('--disable-blink-features=AutomationControlled')option.add_argument('headless')driver = webdriver.Chrome(options=option)driver.get(PRO_DIR +'\\'+ html_file)# time.sleep(2)# sig = driver.execute_script('return window.aaa()')# print(sig)return driver
html_file = 'index.html'
driv = driver_sig(html_file)
print(driv.execute_script('return window.aaa()'))
3.实现接口
pip install flask
from flask import Flask
# 创建 Flask 应用实例
app = Flask(__name__)
# 定义路由和视图函数
@app.route('/')
def hello():return 'Hello, Flask!'
# 启动应用
if __name__ == '__main__':app.run()
- Flask 是一个基于 Python 的轻量级、简单易用的 Web 应用框架。它提供了一个灵活且容易扩展的方式来构建 Web 应用程序。以下是一个简单的示例展示了如何使用 Flask 框架创建一个简易的 Web 应用:
- 在上述示例中,我们首先导入了 Flask 模块,并创建了一个 Flask 应用实例 app。然后,使用 @app.route() 装饰器定义了一个路由以及对应的视图函数。在本例中,根路由 '/' 对应的视图函数是 hello(),它返回了一个简单的字符串 'Hello, Flask!'。最后,通过调用 app.run() 来启动应用。
- 要运行这个应用,你需要确保已经安装了 Flask 模块。运行应用后,在浏览器中访问 http://localhost:5000/,你将看到输出的 'Hello, Flask!'。
1.实际使用
# -*- coding: utf-8 -*-
from flask import Flask, request
from selenium import webdriver
import os
from selenium.webdriver.common.by import By
# pip install flask
from flask import Flask, jsonify
PRO_DIR = os.path.dirname(os.path.abspath(__file__))
def driver_sig(html_file):option = webdriver.ChromeOptions()option.add_argument('--disable-blink-features=AutomationControlled')option.add_argument('headless')driver = webdriver.Chrome(options=option)driver.get(PRO_DIR + '\\' + html_file)# time.sleep(2)# sig = driver.execute_script('return window.aaa()')# print(sig)return driver
html_file = 'index.html'
driv = driver_sig(html_file)
# 创建 Flask 应用实例
app = Flask(__name__)
# 定义路由和视图函数
@app.route('/s', methods=['get', 'post'])
def hello():context = {# 加载本地地址 生成cookie值'v': driv.execute_script('return window.aaa()')}# 返回cookie值return jsonify(context=context)
# 启动应用
if __name__ == '__main__':app.run()
RPC
1. RPC 简介
为什么要使用RPC技术呢?我们在使用websocket时候可以发现,python在操作的时候,需要创建连接,还需要不断去接受传递数据,非常的麻烦, 那这个时候rpc技术可以帮助到我们,简单来说就是网页直接和rpc服务器进行交互,我们python可以直接调用,rpc暴露的接口,不需要关心,创建连接这一块的问题.
RPC 技术是非常复杂的,对于我们搞爬虫、逆向的来说,不需要完全了解,只需要知道这项技术如何在逆向中应用就行了。
RPC 在逆向中,简单来说就是将本地和浏览器,看做是服务端和客户端,二者之间通过 WebSocket 协议进行 RPC 通信,在浏览器中将加密函数暴露出来,在本地直接调用浏览器中对应的加密函数,从而得到加密结果,不必去在意函数具体的执行逻辑,也省去了扣代码、补环境等操作,可以省去大量的逆向调试时间。
补环境案例
案例站:688262.SH - 同花顺问财
接口:
找加密位置
xhr断点发现段不住,原因就是他不是ajax发包的
请求堆栈里面断点
这个地方的接口是公用的
往上多看几个站,发现是在这里弄的
但是发现这里也是公用的多过几个
这个时候并没有加密,逐行运行
f10一次之后发现就加密了
所以是 document.getElementsByTagName("head")[0].appendChild(d),加密的
f11进去
r是script标签
所以加密的方法就在
L方法里面
把整个文件扣下来
因为他是动态的,所以我们请求这个文件,在改代码
网站的调用方式是
var d = document.createElement("script");e.cache || n.cache ? d.setAttribute("src", "" + o) : (o += -1 === o.indexOf("?") ? "?" : "&",d.setAttribute("src", "" + o + s + "=" + c)),e.charset && d.setAttribute("charset", e.charset),d.id = f,document.getElementsByTagName("head")[0].appendChild(d),
我们也这么干
var d = document.createElement("script");// # e.cache || n.cache ? d.setAttribute("src", "" + o) : (o += -1 === o.indexOf("?") ? "?" : "&",d.setAttribute("src","https://d.10jqka.com.cn/v6/line/17_688262/01/today.jscallback=quotebridge_v6_line_17_688262_01_today"),// #e.charset && d.setAttribute("charset", e.charset),d.id ="callback_quotebridge_v6_line_17_688262_01_today",document.getElementsByTagName("head")[0].appendChild(d)
那我们在浏览器运行成功了,下一步放在node.js里面
运行
开始补环境
方法1:传统补
对比发现真实的环境中q是ture,所以这里逻辑有问题,找到赋值的位置
方法二-jsdom
我们在开头加入
const jsdom = require("jsdom");
const {JSDOM} = jsdom;
var dom = new JSDOM('<!DOCTYPE html><p>hello world</p>')
window = dom.window
document = dom.window.document
Document=dom.window.Document
// console.log(dom.window.document)
navigator = dom.window.navigator
Element=dom.window.Element
// Element =function Element(){}
Element.prototype.insertBefore=function insertBefore(d){window.perry=d.src}location=dom.window.location
location.href='https://www.iwencai.com/unifiedwap/result?w=688262.SH%20&querytype=stock'
location.hostname='www.iwencai.com'
location.host='www.iwencai.com'
location.protocol='http:'navigator.userAgent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'Document.prototype.getElementsByTagName=function getElementsByTagName(){return [{appendChild:function (d){Element.prototype.insertBefore(d)}}]
}
运行
发现成功,补完了
方法三----利用selenium补环境
运行
也成功了
方法四:rpc
利用rpc技术更快捷,具体使用在我其他blog里面,具体看https://articles.zsxq.com/id_cxu1hc2vub8x.html
相关文章:

爬虫补环境案例---问财网(rpc,jsdom,代理,selenium)
目录 一.环境检测 1. 什么是环境检测 2.案例讲解 二 .吐环境脚本 1. 简介 2. 基础使用方法 3.数据返回 4. 完整代理使用 5. 代理封装 6. 封装所有使用方法 jsdom补环境 1. 环境安装 2. 基本使用 3. 添加参数形式 Selenium补环境 1. 简介 2.实战案例 1. 逆向目…...

SpringBoot有几种获取Request对象的方法
HttpServletRequest 简称 Request,它是一个 Servlet API 提供的对象,用于获取客户端发起的 HTTP 请求信息。例如:获取请求参数、获取请求头、获取 Session 会话信息、获取请求的 IP 地址等信息。 那么问题来了,在 Spring Boot 中…...

在 Windows 11 中使用 MuMu 模拟器 12 国际版配置代理
**以下是优化后的教学内容,使用 Markdown 格式,便于粘贴到 CSDN 或其他支持 Markdown 格式的编辑器中: 在 Windows 11 中使用 MuMu 模拟器 12 国际版配置代理 MuMu 模拟器内有网络设置功能,可以直接在模拟器中配置代理。但如果你不确定如何操作,可以通过在 Windows 端设…...

ASP.NET Core Webapi 返回数据的三种方式
ASP.NET Core为Web API控制器方法返回类型提供了如下几个选择: Specific type IActionResult ActionResult<T> 1. 返回指定类型(Specific type) 最简单的API会返回原生的或者复杂的数据类型(比如,string 或者…...

SQL面试题——蚂蚁SQL面试题 连续3天减少碳排放量不低于100的用户
连续3天减少碳排放量不低于100的用户 这是一道来自蚂蚁的面试题目,要求我们找出连续3天减少碳排放量低于100的用户,之前我们分析过两道关于连续的问题了 SQL面试题——最大连续登陆问题 SQL面试题——球员连续四次得分 这两个问题都是跟连续有关的,但是球员连续得分的难…...

Python酷库之旅-第三方库Pandas(216)
目录 一、用法精讲 1011、pandas.DatetimeIndex.tz属性 1011-1、语法 1011-2、参数 1011-3、功能 1011-4、返回值 1011-5、说明 1011-6、用法 1011-6-1、数据准备 1011-6-2、代码示例 1011-6-3、结果输出 1012、pandas.DatetimeIndex.freq属性 1012-1、语法 1012…...

论文解析:计算能力资源的可信共享:利益驱动的异构网络服务提供机制
目录 论文解析:计算能力资源的可信共享:利益驱动的异构网络服务提供机制 KM-SMA算法 KM-SMA算法通过不断更新节点的可行顶点标记值(也称为顶标),利用匈牙利方法(Hungarian method)来获取匹配结果。在获取匹配结果后,该算法还会判断该结果是否满足Pareto最优性,即在没…...

Spring AOP技术
1.AOP基本介绍 AOP 的全称 (aspect oriented programming) ,面向切面编程。 1.和传统的面向对象不同。 面向切面编程是根据自我的需求,将切面类的方法切入到其他的类的方法中。(这么说抽象吧!来张图来解释。) 如图 传…...

数字IC实践项目(10)—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证(付费项目)
数字IC实践项目(10)—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证(付费项目) 前言项目框图1)DDR4 Verification IP2)DDR4 JEDEC Model & Tb 项目文件1)DDR4 Veri…...

MATLAB保存多帧图形为视频格式
基本思路 在Matlab中,要将drawnow绘制的多帧数据保存为视频格式,首先需要创建一个视频写入对象。这个对象用于将每一帧图像数据按照视频格式的要求进行组合和编码。然后,在每次drawnow更新绘图后,将当前的图形窗口内容捕获为一帧图…...

redis7.x源码分析:(3) dict字典
dict字典采用经典hash表数据结构实现,由键值对组成,类似于C中的unordered_map。两者在代码实现层面存在一些差异,比如gnustl的unordered_map分配的桶数组个数是(质数n),而dict分配的桶数组个数是࿰…...

连续九届EI稳定|江苏科技大学主办
【九届EI检索稳定|江苏科技大学主办 | IEEE出版 】 🎈【截稿倒计时】!!! ✨徐秘书:gsra_huang ✨往届均已检索,已上线IEEE官网 🎊第九届清洁能源与发电技术国际学术会议(CEPGT 2…...

HarmonyOS NEXT应用开发实战 ( 应用的签名、打包上架,各种证书详解)
前言 没经历过的童鞋,首次对HarmonyOS的应用签名打包上架可能感觉繁琐。需要各种秘钥证书生成和申请,混在一起也分不清。其实搞清楚后也就那会事,各个文件都有它存在的作用。 HarmonyOS通过数字证书与Profile文件等签名信息来保证鸿蒙应用/…...

【CICD】CICD 持续集成与持续交付在测试中的应用
一、什么是CICD? CI/CD 是指持续集成(Continuous Integration)和持续部署(Continuous Deployment)或持续交付(Continuous Delivery) 1.1 持续集成(Continuous Integration…...

Dolby TrueHD和Dolby Digital Plus (E-AC-3)编码介绍
文章目录 1. Dolby TrueHD特点总结 2. Dolby Digital Plus (E-AC-3)特点总结 Dolby TrueHD 与 Dolby Digital Plus (E-AC-3) 的对比 Dolby TrueHD和Dolby Digital Plus (E-AC-3) 是两种高级的杜比音频编码格式,常用于蓝光影碟、流媒体、影院等高品质音频传输场景。它…...

数字频率计的设计-- 基于 HDL 方法
目录 数字频率计的设计 1.计数、锁存与显示译码电路设计 2.主控电路设计 3.分频电路设计 4.顶层电路设计 伪随机序列发生器 的设计 数字频率计的设计 基于HDL设计数字系统时,可以根据需要应用Verilog HDL描述所需要的功能电路,既有利于节约资源&am…...

[程序员] 没有产生core文件的原因
最近和同事一块看一个core文件没有产生的问题,总结了一些在CSDN的专栏里。分析的过程,参考使用了ftrace的功能,感觉非常实用。 如果有需要可以参考。大体上就这么几种情况:信号的特殊处理,coredump相关的配置没有设置正确,文件系统访问权限问题,setuid相关的不匹配问题。…...

【数字图像处理+MATLAB】基于 Sobel 算子计算图像梯度并进行边缘增强:使用 imgradientxy 函数
引言 在图像处理中,边缘通常是图像中像素强度变化最大的地方,这种变化可以通过计算图像的梯度来量化。梯度是一个向量,它的方向指向像素强度增加最快的方向,它的大小(或者说幅度)表示像素强度增加的速度。…...

P10901 [蓝桥杯 2024 省 C] 封闭图形个数
铁子们好呀,今天博主给大家更新一道编程题!!! 题目链接如下: P10901 [蓝桥杯 2024 省 C] 封闭图形个数 好,接下来,我将从三个方面讲解这道例题。分别是 题目解析算法原理代码实现 文章目录 1.题…...

ubuntu-desktop-24.04上手指南(更新阿里源、安装ssh、安装chrome、设置固定IP、安装搜狗输入法)
ubuntu-desktop-24.04上手指南(更新阿里源、安装ssh、安装chrome、设置固定IP、安装搜狗输入法) 一、更新并安装基础软件 #切换root用户 sudo su -#更新 apt update #升级 apt upgrade#install vim apt install vim#install net-tools apt install net-tools二、安装ssh并设置…...

手机直连卫星NTN通信初步研究
目录 1、手机直连卫星之序幕 2、卫星NTN及其网络架构 2.1 NTN 2.2 NTN网络架构 3、NTN的3GPP标准化进程 3.1 NTN需要适应的特性 3.2 NTN频段 3.3 NTN的3GPP标准化进程概况 3.4 NTN的3GPP标准化进程的详情 3.4.1 NR-NTN 3.4.1.1 NTN 的无线相关 SI/WI 3.4.1.2…...

蓝桥杯c++算法学习【2】之搜索与查找(九宫格、穿越雷区、迷宫与陷阱、扫地机器人:::非常典型的必刷例题!!!)
别忘了请点个赞收藏关注支持一下博主喵!!! 关注博主,更多蓝桥杯nice题目静待更新:) 搜索与查找 一、九宫格 【问题描述】 小明最近在教邻居家的小朋友小学奥数,而最近正好讲述到了三阶幻方这个部分,三 …...

Android加载pdf
依赖 implementation com.squareup.okhttp3:okhttp:4.9.1 implementation com.github.barteksc:android-pdf-viewer:3.2.0-beta.1在project.build中添加该源 maven { url "https://repository.liferay.com/nexus/content/repositories/public/" }XML <LinearLa…...

IOT物联网低代码可视化大屏解决方案汇总
目录 参考来源云服务商阿里云物联网平台产品主页产品文档 开源项目DGIOT | 轻量级工业物联网开源平台项目特点项目地址开源许可 IoTGateway | 基于.NET6的跨平台工业物联网网关项目特点项目地址开源许可 IoTSharp | 基于.Net Core开源的物联网基础平台项目特点项目地址开源许可…...

Python的面向对象day7
1、什么是面向对象 面向对象称为OO,他通过将数据和功能封装在一个被称为‘对象’的实体中,来组织和管理代码。面向对象变成(OOP)具有四个特性,封装、继承、多态、抽象 优点:模块化、安全性高、代码重用性…...

计算机网络(11)和流量控制补充
这一篇对数据链路层中的和流量控制进行详细学习 流量控制(Flow Control)是计算机网络中确保数据流平稳传输的技术,旨在防止数据发送方发送过多数据,导致接收方的缓冲区溢出,进而造成数据丢失或传输失败。流量控制通常…...

Rust 所有权机制
Rust 所有权机制 本文示例代码地址 所有权是Rust中最独特的特性,它让Rust无需GC就可以保证内存安全。 什么是所有权? 所有权(ownership)是 Rust 用于如何管理内存的一组规则。所有程序都必须管理其运行时使用计算机内存的方式…...

Pwn VM writeup
国赛期间,做了一个很有意思的pwn题,顺便学了一下现在常见的pwn的板子题是什么样子的,这里做一下记录 Magic VM 题目逻辑 题目本身其实非常的有趣,它实现了一个简易流水线的功能,程序中包含四个结构体,其中三…...

LSTM(长短期记忆网络)详解
1️⃣ LSTM介绍 标准的RNN存在梯度消失和梯度爆炸问题,无法捕捉长期依赖关系。那么如何理解这个长期依赖关系呢? 例如,有一个语言模型基于先前的词来预测下一个词,我们有一句话 “the clouds are in the sky”,基于&…...

机器学习 贝叶斯公式
这是条件概率的计算公式 𝑃(𝐴|𝐵)𝑃(B|A)𝑃(𝐴)/𝑃(𝐵) 全概率公式 𝑃(𝐵)𝑃(𝐵|𝐴)𝑃(𝐴)&am…...