第28讲:JavaScript 逆向爬取实战(上)
上个课时我们介绍了网页防护技术,包括接口加密和 JavaScript 压缩、加密和混淆。这就引出了一个问题,如果我们碰到了这样的网站,那该怎么去分析和爬取呢?
本课时我们就通过一个案例来介绍一下这种网站的爬取思路,本课时介绍的这个案例网站不仅在 API 接口层有加密,而且前端 JavaScript 也带有压缩和混淆,其前端压缩打包工具使用了现在流行的 Webpack,混淆工具是使用了 javascript-obfuscator,这二者结合起来,前端的代码会变得难以阅读和分析。
如果我们不使用 Selenium 或 Pyppeteer 等工具来模拟浏览器的形式爬取的话,要想直接从接口层面上获取数据,基本上需要一点点调试分析 JavaScript 的调用逻辑、堆栈调用关系来弄清楚整个网站加密的实现方法,我们可以称这个过程叫 JavaScript 逆向。这些接口的加密参数往往都是一些加密算法或编码的组合,完全搞明白其中的逻辑之后,我们就能把这个算法用 Python 模拟出来,从而实现接口的请求了。
案例介绍
案例的地址为:https://dynamic6.scrape.cuiqingcai.com/,页面如图所示。
初看之下并没有什么特殊的,但仔细观察可以发现其 Ajax 请求接口和每部电影的 URL 都包含了加密参数。
比如我们点击任意一部电影,观察一下 URL 的变化,如图所示。
这里我们可以看到详情页的 URL 包含了一个长字符串,看似是一个 Base64 编码的内容。
那么接下来直接看看 Ajax 的请求,我们从列表页的第 1 页到第 10 页依次点一下,观察一下 Ajax 请求是怎样的,如图所示。
可以看到 Ajax 接口的 URL 里面多了一个 token,而且不同的页码 token 是不一样的,这个 token 同样看似是一个 Base64 编码的字符串。
另外更困难的是,这个接口还是有时效性的,如果我们把 Ajax 接口 URL 直接复制下来,短期内是可以访问的,但是过段时间之后就无法访问了,会直接返回 401 状态码。
接下来我们再看下列表页的返回结果,比如我们打开第一个请求,看看第一部电影数据的返回结果,如图所示。
这里我们把看似是第一部电影的返回结果全展开了,但是刚才我们观察到第一部电影的 URL 的链接却为 https://dynamic6.scrape.cuiqingcai.com/detail/ZWYzNCN0ZXVxMGJ0dWEjKC01N3cxcTVvNS0takA5OHh5Z2ltbHlmeHMqLSFpLTAtbWIx,看起来是 Base64 编码,我们解码一下,结果为 ef34#teuq0btua#(-57w1q5o5–j@98xygimlyfxs*-!i-0-mb1,但是看起来似乎还是毫无规律,这个解码后的结果又是怎么来的呢?返回结果里面也并不包含这个字符串,那这又是怎么构造的呢?
再然后,这仅仅是某一个详情页页面的 URL,其真实数据是通过 Ajax 加载的,那么 Ajax 请求又是怎样的呢,我们再观察下,如图所示。
好,这里我们发现其 Ajax 接口除了包含刚才所说的 URL 中携带的字符串,又多了一个 token,同样也是类似 Base64 编码的内容。
那么总结下来这个网站就有如下特点:
- 列表页的 Ajax 接口参数带有加密的 token;
- 详情页的 URL 带有加密 id;
- 详情页的 Ajax 接口参数带有加密 id 和加密 token
那如果我们要想通过接口的形式来爬取,必须要把这些加密 id 和 token 构造出来才行,而且必须要一步步来,首先我们要构造出列表页 Ajax 接口的 token 参数,然后才能获取每部电影的数据信息,然后根据数据信息构造出加密 id 和 token。
OK,到现在为止我们就知道了这个网站接口的加密情况了,我们下一步就是去找这个加密实现逻辑了。
由于是网页,所以其加密逻辑一定藏在前端代码中,但前面我们也说了,前端为了保护其接口加密逻辑不被轻易分析出来,会采取压缩、混淆的方式来加大分析的难度。
接下来,我们就来看看这个网站的源代码和 JavaScript 文件是怎样的吧。
首先看看网站源代码,我们在网站上点击右键,弹出选项菜单,然后点击“查看源代码”,可以看到结果如图所示。
内容如下:
<!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"><link rel=icon href=/favicon.ico><title>Scrape | Movie</title><link href=/css/chunk-19c920f8.2a6496e0.css rel=prefetch><link href=/css/chunk-2f73b8f3.5b462e16.css rel=prefetch><link href=/js/chunk-19c920f8.c3a1129d.js rel=prefetch><link href=/js/chunk-2f73b8f3.8f2fc3cd.js rel=prefetch><link href=/js/chunk-4dec7ef0.e4c2b130.js rel=prefetch><link href=/css/app.ea9d802a.css rel=preload as=style><link href=/js/app.5ef0d454.js rel=preload as=script><link href=/js/chunk-vendors.77daf991.js rel=preload as=script><link href=/css/app.ea9d802a.css rel=stylesheet></head><body><noscript><strong>We're sorry but portal doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.77daf991.js></script><script src=/js/app.5ef0d454.js></script></body></html>
这是一个典型的 SPA(单页 Web 应用)的页面, 其 JavaScript 文件名带有编码字符、chunk、vendors 等关键字,整体就是经过 Webpack 打包压缩后的源代码,目前主流的前端开发,如 Vue.js、React.js 的输出结果都是类似这样的结果。
好,那么我们再看下其 JavaScript 代码是什么样子的,我们在开发者工具中打开 Sources 选项卡下的 Page 选项卡,然后打开 js 文件夹,这里我们就能看到 JavaScript 的源代码,如图所示。
我们随便复制一些出来,看看是什么样子的,结果如下:
\(window\['webpackJsonp'\]=window\['webpackJsonp'\]\|\|\[\]\)\['push'\]\(\[\['chunk\-19c920f8'\]\,\{'5a19':function\(\_0x3cb7c3\,\_0x5cb6ab\,\_0x5f5010\)\{\}\,'c6bf':function\(\_0x1846fe\,\_0x459c04\,\_0x1ff8e3\)\{\}\,'ca9c':function\(\_0x195201\,\_0xc41ead\,\_0x1b389c\)\{'use strict';var \_0x468b4e=\_0x1b389c\('5a19'\)\,\_0x232454=\_0x1b389c['n'](_0x468b4e);\_0x232454['a'];},'d504':...,[\_0xd670a1['\_v'](_0xd670a1%5B'_s'%5D(_0x2227b6)+'%5Cx0a%5Cx20%5Cx20%5Cx20%5Cx20%5Cx20%5Cx20%5Cx20%5Cx20%5Cx20%5Cx20%5Cx20%5Cx20%5Cx20%5Cx20')]);}),0x1),\_0x4ef533('div',{'staticClass':'m-v-sm\x20info'},[\_0x4ef533('span',[\_0xd670a1['\_v'](_0xd670a1%5B'_s'%5D(_0x1cc7eb%5B'regions'%5D%5B'join'%5D('%E3%80%81')))]),\_0x4ef533('span',[\_0xd670a1['\_v']('%5Cx20/%5Cx20')]),\_0x4ef533('span',[\_0xd670a1['\_v'](_0xd670a1%5B'_s'%5D(_0x1cc7eb%5B'minute'%5D)+'%5Cx20%E5%88%86%E9%92%9F')])]),\_0x4ef533('div',...,\_0x4ef533('el-col',{'attrs':{'xs':0x5,'sm':0x5,'md':0x4}},[\_0x4ef533('p',{'staticClass':'score\x20m-t-md\x20m-b-n-sm'},[\_0xd670a1['\_v'](_0xd670a1%5B'_s'%5D(_0x1cc7eb%5B'score'%5D%5B'toFixed'%5D(0x1)))\]\)\,\_0x4ef533\('p'\,\[\_0x4ef533\('el\-rate'\,\{'attrs':\{'value':\_0x1cc7eb\['score'\]/0x2\,'disabled':''\,'max':0x5\,'text\-color':'\#ff9900'\}\}\)\]\,0x1\)\]\)\]\,0x1\)\]\,0x1\);\}\)\,0x1\)\]\,0x1\)\,\_0x4ef533\('el\-row'\,\[\_0x4ef533\('el\-col'\,\{'attrs':\{'span':0xa\,'offset':0xb\}\}\,\[\_0x4ef533\('div'\,\{'staticClass':'pagination\x20m\-v\-lg'\}\,\[\_0x4ef533\('el\-pagination'\,\.\.\.:function\(\_0x347c29\)\{\_0xd670a1\['page'\]=\_0x347c29;\}\,'update:current\-page':function\(\_0x79754e\)\{\_0xd670a1\['page'\]=\_0x79754e;\}\}\}\)\]\,0x1\)\]\)\]\,0x1\)\]\,0x1\);\}\,\_0x357ebc=\[\]\,\_0x18b11a=\_0x1a3e60\('7d92'\)\,\_0x4369=\_0x1a3e60\('3e22'\)\,\.\.\.;var \_0x498df8=\.\.\.\['then'\]\(function\(\_0x59d600\)\{var \_0x1249bc=\_0x59d600\['data'\]\,\_0x10e324=\_0x1249bc\['results'\]\,\_0x47d41b=\_0x1249bc\['count'\];\_0x531b38\['loading'\]=\!0x1\,\_0x531b38\['movies'\]=\_0x10e324\,\_0x531b38\['total'\]=\_0x47d41b;\}\);\}\}\}\,\_0x28192a=\_0x5f39bd\,\_0x5f5978=\(\_0x1a3e60\('ca9c'\)\,\_0x1a3e60\('eb45'\)\,\_0x1a3e60\('2877'\)\)\,\_0x3fae81=Object\(\_0x5f5978\['a'\]\)\(\_0x28192a\,\_0x443d6e\,\_0x357ebc\,\!0x1\,null\,'724ecf3b'\,null\);\_0x6f764c\['default'\]=\_0x3fae81\['exports'\];\}\,'eb45':function\(\_0x1d3c3c\,\_0x52e11c\,\_0x3f1276\)\{'use strict';var \_0x79046c=\_0x3f1276\('c6bf'\)\,\_0x219366=\_0x3f1276['n'](_0x79046c);\_0x219366['a'];}}]);
就是这种感觉,可以看到一些变量都是一些十六进制字符串,而且代码全被压缩了。
没错,我们就是要从这里面找出 token 和 id 的构造逻辑,看起来是不是很崩溃?
要完全分析出整个网站的加密逻辑还是有一定难度的,不过不用担心,我们本课时会一步步地讲解逆向的思路、方法和技巧,如果你能跟着这个过程学习完,相信还是能学会一定的 JavaScript 逆向技巧的。
为了适当降低难度,本课时案例的 JavaScript 混淆其实并没有设置的特别复杂,并没有开启字符串编码、控制流扁平化等混淆方式。
列表页 Ajax 入口寻找
接下来,我们就开始第一步入口的寻找吧,这里简单介绍两种寻找入口的方式:
- 全局搜索标志字符串;
- 设置 Ajax 断点。
全局搜索标志字符串
一些关键的字符串通常会作为找寻 JavaScript 混淆入口的依据,我们可以通过全局搜索的方式来查找,然后根据搜索到的结果大体观察是否是我们想找的入口。
然后,我们重新打开列表页的 Ajax 接口,看下请求的 Ajax 接口,如图所示。
这里的 Ajax 接口的 URL 为 https://dynamic6.scrape.cuiqingcai.com/api/movie/?limit=10&offset=0&token=NTRhYWJhNzAyYTZiMTc0ZThkZTExNzBiNTMyMDJkN2UxZWYyMmNiZCwxNTg4MTc4NTYz,可以看到带有 offset、limit、token 三个参数,入口寻找关键就是找 token,我们全局搜索下 token 是否存在,可以点击开发者工具右上角的下拉选项卡,然后点击 Search,如图所示。
这样我们就能进入到一个全局搜索模式,我们搜索 token,可以看到的确搜索到了几个结果,如图所示。
观察一下,下面的两个结果可能是我们想要的,我们点击进入第一个看下,定位到了一个 JavaScript 文件,如图所示。
这时候可以看到整个代码都是压缩过的,只有一行,不好看,我们可以点击左下角的 {} 按钮,美化一下 JavaScript 代码,如图所示。
美化后的结果就是这样子了,如图所示。
这时可以看到这里弹出来了一个新的选项卡,其名称是 JavaScript 文件名加上了 :formatted,代表格式化后代码结果,在这里我们再次定位到 token 观察一下。
可以看到这里有 limit、offset、token,然后观察下其他的逻辑,基本上能够确定这就是构造 Ajax 请求的地方了,如果不是的话可以继续搜索其他的文件观察下。
那现在,混淆的入口点我们就成功找到了,这是一个首选的找入口的方法。
XHR 断点
由于这里的 token 字符串并没有被混淆,所以上面的这个方法是奏效的。之前我们也讲过,这种字符串由于非常容易成为找寻入口点的依据,所以这样的字符串也会被混淆成类似 Unicode、Base64、RC4 的一些编码形式,这样我们就没法轻松搜索到了。
那如果遇到这种情况,我们该怎么办呢?这里再介绍一种通过打 XHR 断点的方式来寻找入口。
XHR 断点,顾名思义,就是在发起 XHR 的时候进入断点调试模式,JavaScript 会在发起 Ajax 请求的时候停住,这时候我们可以通过当前的调用栈的逻辑顺着找到入口。怎么设置呢?我们可以在 Sources 选项卡的右侧,XHR/fetch Breakpoints 处添加一个断点选项。
首先点击 + 号,然后输入匹配的 URL 内容,由于 Ajax 接口的形式是 /api/movie/?limit=10… 这样的格式,所这里我们就截取一段填进去就好了,这里填的就是 /api/movie,如图所示。
添加完毕之后重新刷新页面,可以发现进入了断点模式,如图所示。
那这里看到有个 send 的字符,我们可以初步猜测这就是相当于发送 Ajax 请求的一瞬间。
到了这里感觉 Ajax 马上就要发出去了,是不是有点太晚了,我们想找的是构造 Ajax 的时刻来分析 Ajax 参数啊!不用担心,这里我们通过调用栈就可以找回去。我们点击右侧的 Call Stack,这里记录了 JavaScript 的方法逐层调用过程,如图所示。
这里当前指向的是一个名字为 anonymouns,也就是匿名的调用,在它的下方就显示了调用这个 anonymouns 的方法,名字叫作 _0x594ca1,然后再下一层就又显示了调用 _0x594a1 这个方法的方法,依次类推。
这里我们可以逐个往下查找,然后通过一些观察看看有没有 token 这样的信息,就能找到对应的位置了,最后我们就可以找到 onFetchData 这个方法里面实现了这个 token 的构造逻辑,这样我们也成功找到 token 的参数构造的位置了,如图所示。
好,到现在为止我们就通过两个方法找到入口点了。
其实还有其他的寻找入口的方式,比如 Hook 关键函数的方式,稍后的课程里我们会讲到,这里就暂时不讲了。
列表页加密逻辑寻找
接下来我们已经找到 token 的位置了,可以观察一下这个 token 对应的变量叫作 _0xa70fc9,所以我们的关键就是要找这个变量是哪里来的了。
怎么找呢?我们打个断点看下这个变量是在哪里生成的就好了,我们在对应的行打一个断点,如果打了刚才的 XHR 断点的话可以先取消掉,如图所示。
这时候我们就设置了一个新的断点了。由于只有一个断点,可以重新刷新下网页,这时候我们会发现网页停在了新的断点上面。
这里我们就可以观察下运行的一些变量了,比如我们把鼠标放在各个变量上面去,可以看到变量的一些值和类型,比如我们看 _0x18b11a 这个变量,会有一个浮窗显示,如图所示。
另外我们还可以通过在右侧的 Watch 面板添加想要查看的变量名称,如这行代码的内容为:
, _0xa70fc9 = Object(_0x18b11a['a'])(this['$store']['state']['url']['index']);
我们比较感兴趣的可能就是 _0x18b11a 还有 this 里面的这个值了,我们可以展开 Watch 面板,然后点击 + 号,把想看的变量添加到 Watch 面板里面,如图所示。
观察下可以发现 _0x18b11a 是一个 Object,它有个 a 属性,其值是一个 function,然后 this[’$store’][‘state’][‘url’][‘index’] 的值其实就是 /api/movie,就是 Ajax 请求 URL 的 Path。_0xa70fc9 就是调用了前者这个 function 然后传入了 /api/movie 得到的。
那么下一步就是去寻找这个 function 在哪里了,我们可以把 Watch 面板的 _0x18b11a 展开,这里会显示一个 FunctionLocation,就是这个 function 的代码位置,如图所示。
点击进入之后发现其仍然是未格式化的代码,再次点击 {} 格式化代码。
这时候我们就进入了一个新的名字为 _0xc9e475 的方法里面,这个方法里面应该就是 token 的生成逻辑了,我们再打上断点,然后执行面板右上角蓝色箭头状的 Resume 按钮,如图所
这时候发现我们已经单步执行到这个位置了。
接下来我们不断进行单步调试,观察这里面的执行逻辑和每一步调试过程中结果都有什么变化,如图所示。
在每步的执行过程中,我们可以发现一些运行值会被打到代码的右侧并带有高亮表示,同时在 watch 面板还能看到每步的变量的具体结果。
最后我们总结出这个 token 的构造逻辑如下:
- 传入的 /api/movie 会构造一个初始化列表,变量命名为 _0x3dde76。
- 获取当前的时间戳,命名为 _0x4c50b4,push 到 _0x3dde76 这个变量里面。
- 将 _0x3dde76 变量用“,”拼接,然后进行 SHA1 编码,命名为 _0x46ba68。
- 将 _0x46ba68 (SHA1 编码的结果)和 _0x4c50b4 (时间戳)用逗号拼接,命名为 _0x495a44。
- 将 _0x495a44 进行 Base64 编码,命名为 _0x2a93f2,得到最后的 token。
以上的一些逻辑经过反复的观察就可以比较轻松地总结出来了,其中有些变量可以实时查看,同时也可以自己输入到控制台上进行反复验证,相信总结出这个结果并不难。
好,那现在加密逻辑我们就分析出来啦,基本的思路就是:
- 先将 /api/movie 放到一个列表里面;
- 列表中加入当前时间戳;
- 将列表内容用逗号拼接;
- 将拼接的结果进行 SHA1 编码;
- 将编码的结果和时间戳再次拼接;
- 将拼接后的结果进行 Base64 编码。
验证下逻辑没问题的话,我们就可以用 Python 来实现出来啦。
Python 实现列表页的爬取
要用 Python 实现这个逻辑,我们需要借助于两个库,一个是 hashlib,它提供了 sha1 方法;另外一个是 base64 库,它提供了 b64encode 方法对结果进行 Base64 编码。
代码实现如下:
import hashlib
import time
import base64
from typing import List, Any
import requestsINDEX\_URL = 'https://dynamic6.scrape.cuiqingcai.com/api/movie?limit={limit}&offset={offset}&token={token}'
LIMIT = 10
OFFSET = 0def get\_token(args: List[Any]):
timestamp = str(int(time.time()))
args.append(timestamp)
sign = hashlib.sha1(','.join(args).encode('utf-8')).hexdigest()
return base64.b64encode(','.join([sign, timestamp]).encode('utf-8')).decode('utf-8')args = ['/api/movie']
token = get\_token(args=args)
index\_url = INDEX\_URL.format(limit=LIMIT, offset=OFFSET, token=token)
response = requests.get(index\_url)
print('response', response.json())
这里我们就根据上面的逻辑把加密流程实现出来了,这里我们先模拟爬取了第一页的内容,最后运行一下就可以得到最终的输出结果了。
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- 智能优化算法:飞蛾扑火优化算法-附代码
智能优化算法:飞蛾扑火优化算法-附代码 文章目录智能优化算法:飞蛾扑火优化算法-附代码1.算法原理2.算法流程3.算法结果4.参考文献5.MATLAB代码 摘要:飞饿扑火优 化 算 法 ( Moth-flame optimization algorithm,MFO) 是Seyedali Mirjalili等于2015年提出的一种新型智能优化…...
2024/5/3 7:46:56 - C++知识点总结
1.c和c++的区别是什么?程序 = 数据结构+算法.c语言是面向过程的,面向过程就是分析出解决问题的步骤,然后用函数将其实现,使用时依次调用.程序= 对象+消息.c++是面向对象的,c++面向对象是将构成问题的事物分解成各个对象,每个对象完成在解决整个问题中的行为.主要特点是类,封…...
2024/5/6 13:28:30 - IDataReader在没有任何数据时进行无效的读取尝试。
不要漏掉IDataReader.Read() 不要漏掉IDataReader.Read() 不要漏掉IDataReader.Read() IDataReader.NextResult()后也要 IDataReader.Read() IDataReader.Read() IDataReader.Read()...
2024/5/8 12:02:38 - 真的可以啊,用C语言实现面向对象编程O O P!C语言真的无所不能~
解释区分一下C语言和OOP我们经常说C语言是面向过程的,而C++是面向对象的,然而何为面向对象,什么又是面向过程呢?不管怎么样,我们最原始的目标只有一个就是实现我们所需要的功能,从这一点说它们是殊途同归的。过程与对象只是侧重点不同而已。举个例子吧,我现在有个计划…...
2024/4/28 7:21:52 - 推荐一个整理免费可商用字体的网站——猫啃网
【推荐一个整理免费可商用字体的网站——猫啃网】 文字版预览页面:[url]https://www.maoken.com/all-fonts[/url] 图文版预览页面:[url]https://www.maoken.com/all-fonts-imgs[/url]这个是我目前看到过的免费可商用字体网站里面对字体的各种具体协议以及相关制作者整理得最清…...
2024/5/8 18:49:19 - Java——数组查找
二分法查找 时间复杂度:O【log(待查找数组长度)】 空间复杂度:O(待查找数组长度) public class Hello {public static void main(String[] args) {int[] input={0,1,5,6,7,8,22,43,90};System.out.println(binarySearch(input, 43));System.out.println(binarySearch(inp…...
2024/4/15 14:47:15 - 豆瓣、网易云热榜词云
1、豆瓣 import requests import json import time import csv import pymysql import codecs from textrank4zh import TextRank4Keyword, TextRank4Sentence import hashlib # import time import random import http.client from lxml import etree import urllib import da…...
2024/5/8 15:48:02 - # 两角和正切的展开式
tan(A+B)=(tanA+tanB)/(1-tanAtanB) (由原来的公式上下同除coscos)...
2024/4/22 15:30:28 - jdk1.8 lambda表达式接口的使用
我们是以jdk1.8。完成接口的使用。 1 定义一个接口,方法中具有多个参数,没有返回值。我们看看使用lambad方式如何使用。 package com.zxf.dLambda; public interface NoneReturnMutipleParameter {//多个参数,无返回值。public void f1(int x,int y); }@Testpublic void te…...
2024/5/8 12:21:30 - Android 8.0以后前台页面显示
转载博客 https://blog.csdn.net/dandelionela/article/details/86092293...
2024/4/22 15:02:42 - 数据结构 C6 图
文章目录6.1图的基本概念6.2图的存储及其基本操作6.2.1邻接矩阵法6.2.2邻接表法6.2.3十字链表6.2.4邻接多重表6.2.5图的基本操作6.3图的遍历6.3.1广度优先搜索6.3.2深度优先算法与树的深度优先遍历之间的联系&& 算法实现复杂度分析深度优先生成树图的遍历和图的连通性6…...
2024/5/7 5:09:04 - 聊一聊Spring统一处理事务 并代码演示案例(整合Mybatis)
文章目录一、基本概念二、程序举例前期准备 一、基本概念 1、什么是事务 讲mysql的时候,提出了事务。事务是指一组sql 语句的集合,集合中有多条sql语句,可能是insert ,update,select ,delete,我们希望这些多个sql语句都能成功,或者都失败,这些sql 语句的执行是一致的,…...
2024/4/23 1:53:13 - 配置集群分发脚本
在/home/atguigu目录下创建bin目录,并在bin目录下创建xsync文件 [atguigu@hadoop101 hadoop] cd /home/atguigu [atguigu@hadoop101 ~] mkdir bin [atguigu@hadoop101 bin] touch xsync [atguigu@hadoop101 bin] vim xsync在该文件中编写如下代码 #!/bin/bash #1. 判断参数个…...
2024/5/7 10:51:22 - ssm下 的一些问题
安装项目的依赖 有些无法让maven 自动下载 要自己去手动安装到Maven本地仓库中 其次遇到 autorwired 注入 显示红色(包能够被扫描到的情况下) project struct 中 删除spring 即可...
2024/4/15 18:37:15 - 安卓终端实现串口通信
在项目用到串口通信或者USB通信,其实就是一个思路找到终端设备连接各个硬件设备的端口,不管是串口还是usb端口,如果不清楚哪个端口建议下载友善助手,通过这个工具可以发送指令集给硬件设备,也可以检测硬件设备返回的指令,知道端口后而我们终端是如何通信的呢?1.首先创建…...
2024/5/8 16:06:24 - FAT16和FAT32目录结构分析
一、前言FAT16和FAT32从原理上看是同一类技术,放在一起分析,有助于了解其细节差异;先回归一下FAT16、FAT32 分区的大致结构如下:从分区结构上看,FAT16和FAT32目录结构比较不一样的地方在于:FAT16 多了一个根目录区,根目录区由FDT目标表项组成,每一个分区表项占32字节;…...
2024/4/30 18:49:39 - 线程池相关问题
线程池相关问题 问题1:为什么要使用线程池,优势是什么? 线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最 大数量超出数量的线程排队等候,等其它线程执行完毕,再从队列中取出任务来执行。 他的主要…...
2024/4/23 10:07:29 - Mybatis批量任务报错
今天进行单字段批量更新的时候,发生了报错。 有时候是传入的值确实,有时候是传入的数据类型不对。 但是,进行debug的时候,发现数据是没有问题的。 最终发现没有开数据库的批量配置。 尴尬!!! 在数据库后加 &allowMultiQueries=true完美解决!!!!...
2024/4/15 18:37:11 - SimpleDateFormat类的日期转化格式
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd hh:mm:ss”)字符串"yyyy-MM-dd hh:mm:ss":yyyy : 代表年(不去区分大小写) 如: 2010"y" , "yyy" , "yyyy" 匹配的都是4位完整的年 如 : "2010"yy" 匹配…...
2024/4/29 14:17:56 - 跟着专注于计算机视觉的AndyJ的妈妈我学算法之每日一题leetcode105从前序与中序遍历序列构造二叉树
DFS. 题目: 105. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树。注意: 你可以假设树中没有重复的元素。例如,给出前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树:3/ \9 20/ \15 7代码: class Sol…...
2024/4/23 0:47:39
最新文章
- android 性能调整方案总结
一 adb方式调整 添加分组来调整对应的优先级: 查看分组信息:/dev/cpuset 要绑定到大核就需要先解决限制的问题 把surfaceflinger echo到forground组,forground的cpus是0-7,涵盖所有核 echo 919 > /dev/cpuset/foreground/task…...
2024/5/8 19:39:42 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/5/7 10:36:02 - redis 集群 (主从复制 哨兵模式 cluster)
目录 一 主从复制 (一)相关理论 1,主从复制定义 2,主从复制的作用 3,主从复制架构图 4 sync 同步过程 5,主从复制流程 (二) 实验模拟 1, 实验环境 2, 修…...
2024/5/7 4:40:28 - 用html实现在页面底部养鱼的效果
<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>在网页底部养鱼</title><link rel"stylesheet" href"./style.css"> </head> <body> <div id"fi…...
2024/5/7 1:08:12 - 416. 分割等和子集问题(动态规划)
题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义:dp[i][j]表示当背包容量为j,用前i个物品是否正好可以将背包填满ÿ…...
2024/5/8 19:32:33 - 【Java】ExcelWriter自适应宽度工具类(支持中文)
工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...
2024/5/7 22:31:36 - Spring cloud负载均衡@LoadBalanced LoadBalancerClient
LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon,直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件,我们讨论Spring负载均衡以Spring Cloud2020之后版本为主,学习Spring Cloud LoadBalance,暂不讨论Ribbon…...
2024/5/8 1:37:40 - TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案
一、背景需求分析 在工业产业园、化工园或生产制造园区中,周界防范意义重大,对园区的安全起到重要的作用。常规的安防方式是采用人员巡查,人力投入成本大而且效率低。周界一旦被破坏或入侵,会影响园区人员和资产安全,…...
2024/5/7 14:19:30 - VB.net WebBrowser网页元素抓取分析方法
在用WebBrowser编程实现网页操作自动化时,常要分析网页Html,例如网页在加载数据时,常会显示“系统处理中,请稍候..”,我们需要在数据加载完成后才能继续下一步操作,如何抓取这个信息的网页html元素变化&…...
2024/5/8 1:37:39 - 【Objective-C】Objective-C汇总
方法定义 参考:https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...
2024/5/7 16:57:02 - 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】
👨💻博客主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】🌏题目描述🌏输入格…...
2024/5/7 14:58:59 - 【ES6.0】- 扩展运算符(...)
【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数࿰…...
2024/5/7 1:54:46 - 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?
文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕,各大品牌纷纷晒出优异的成绩单,摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称,在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁,多个平台数据都表现出极度异常…...
2024/5/7 21:15:55 - Go语言常用命令详解(二)
文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令,这些命令可以帮助您在Go开发中进行编译、测试、运行和…...
2024/5/8 1:37:35 - 用欧拉路径判断图同构推出reverse合法性:1116T4
http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b,我们在 a i a_i ai 和 a i 1 a_{i1} ai1 之间连边, b b b 同理,则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然࿰…...
2024/5/7 16:05:05 - 【NGINX--1】基础知识
1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息,并安装一些有助于配置官方 NGINX 软件包仓库的软件包: apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...
2024/5/8 18:06:50 - Hive默认分割符、存储格式与数据压缩
目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限(ROW FORMAT)配置标准HQL为: ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...
2024/5/8 1:37:32 - 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法
文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中,传感器和控制器产生大量周…...
2024/5/7 16:05:05 - --max-old-space-size=8192报错
vue项目运行时,如果经常运行慢,崩溃停止服务,报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中,通过JavaScript使用内存时只能使用部分内存(64位系统&…...
2024/5/8 1:37:31 - 基于深度学习的恶意软件检测
恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞,例如可以被劫持的合法软件(例如浏览器或 Web 应用程序插件)中的错误。 恶意软件渗透可能会造成灾难性的后果,包括数据被盗、勒索或网…...
2024/5/8 1:37:31 - JS原型对象prototype
让我简单的为大家介绍一下原型对象prototype吧! 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象…...
2024/5/8 12:44:41 - C++中只能有一个实例的单例类
C中只能有一个实例的单例类 前面讨论的 President 类很不错,但存在一个缺陷:无法禁止通过实例化多个对象来创建多名总统: President One, Two, Three; 由于复制构造函数是私有的,其中每个对象都是不可复制的,但您的目…...
2024/5/8 9:51:44 - python django 小程序图书借阅源码
开发工具: PyCharm,mysql5.7,微信开发者工具 技术说明: python django html 小程序 功能介绍: 用户端: 登录注册(含授权登录) 首页显示搜索图书,轮播图࿰…...
2024/5/8 1:37:29 - 电子学会C/C++编程等级考试2022年03月(一级)真题解析
C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...
2024/5/7 17:09:45 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57