IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 爬虫之js分析解决图片置乱问题 -> 正文阅读

[JavaScript知识库]爬虫之js分析解决图片置乱问题


前言

最近在爬一个网站图片的时候,发生了一件很有意思的事。当我拿到图片链接后打开发现它和加载出来的图片不一样啊,细看后发现原图片是被切片成了多段后倒序拼接在一起的。(给兄弟萌整两张图片看看嗷)当时我整个人就不对劲了,但我是谁?爬虫小能手(自吹的),我能受着气?直接逮着就是一顿输出嗷。

原图片:
在这里插入图片描述
加载出来的图片:
在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、思路分析

一个优秀的爬虫选手,第一步都应该是整理思路,理清前后的逻辑关系。
我们先来看一下整个网页的html代码,找到img标签那块看看
在这里插入图片描述
然后我们就看出来了,这啥也没有,这只放了一堆原图的链接屁用没有。
此时我们直接F12,打开开发者模式看看,我们直接定位到图片
在这里插入图片描述
哟哟哟,怎么多出来个canvas标签啊,此时的思路一下就明了了,说一下我当时大概的猜测吧:我觉得应该是在加载图片时动态生成了canvas标签,然后通过canvas标签的drawImage方法成功将图片加载出来。
现在我们就需要验证这个思路究竟是不是正确的,怎么来验证了?划重点:动态生成canvas标签,是不是就等同于存在document.createElement(“canvas”),那我们直接到top文件夹下搜索canvas字段试试
在这里插入图片描述
哦哟哟哟,不得了不得了,还真让我搜出点东西嗷。很明显最后两个js文件又猫腻,那我们的思路分析就到此结束,下一步就是分析js代码了。

二、细说JS

1.JS分析

我们先来看一看第一个js文件
第一处:
在这里插入图片描述
第二处:
在这里插入图片描述
第三处:
在这里插入图片描述
第一个文件里面有三处含有canvas,可是很遗憾没有找到我们想要的信息。那我们就只能看看第二个js文件了。
在这里插入图片描述
卧槽,差点没绷住,很明显这个js文件的代码全被混淆了,要想接着走下去我们就只有先把混淆的代码想办法弄出来。

2.搞定JS混淆

我们细看的话可以发现,上面的混淆代码可以分成4个函数,分别是
第一个:在这里插入图片描述
第二个:
在这里插入图片描述
第三个:
在这里插入图片描述
第四个:
在这里插入图片描述
这样细分下来就可以看出一些东西了:
第一点:这里执行了两个方法,就是三和四
第二点:最后的方法里面返回的应该是一段字符串而且还是一段代码,因为它用了eval()
那我们现在应该怎么做了?很简单嘛,四个函数挨个扔到控制台里面,跑一下不就行了?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们这里对最后两个函数处理了一下,定义了一个函数名,方便我们调用。接下来我们就调用一下试试看嗷:
首先是调用A函数也就是第三个,传入的参数就是它原方法下面括号里的参数
在这里插入图片描述
然后再调用B函数,和A函数方法一样
在这里插入图片描述
哟哟哟,这不就来了吗?这就到了第三步了。

3.最终分析

我们先复制下来,然后代码格式化后看看

function scramble_image(e, t, a, n, d) {
	n || (n = !1), d || (d = !1), e.src.indexOf(".jpg") < 0 || parseInt(t) < parseInt(a) || "1" == d ? "none" === e.style.display && (e.style.display = "block") : 1 == n || 0 == e.complete ? document.getElementById(e.id)
		.onload = function() {
			onImageLoaded(e)
		} : onImageLoaded(e)
}

function onImageLoaded(e) {
	var t;
	null == e.nextElementSibling ? (t = document.createElement("canvas"), e.after(t)) : t = document.getElementById(e.id)
		.nextElementSibling;
	var a = t.getContext("2d"),
		n = e.width,
		d = e.naturalWidth,
		i = e.naturalHeight;
	t.width = d, t.height = i, (n > e.parentNode.offsetWidth || 0 == n) && (n = e.parentNode.offsetWidth), t.style.width = n + "px", t.style.display = "block";
	var r = document.getElementById(e.id)
		.parentNode;
	r = (r = r.id.split("."))[0];
	for (var s = get_num(aid, r), l = parseInt(i % s), o = d, m = 0; m < s; m++) {
		var c = Math.floor(i / s),
			g = c * m,
			h = i - c * (m + 1) - l;
		0 == m ? c += l : g += l, a.drawImage(e, 0, h, o, c, 0, g, o, c)
	}
	$(e)
		.addClass("hide")
}

function showBig(e, t, a) {
	var n = document.getElementById("popup");
	if (n.onclick = function() {
		n.style.display = "none"
	}, t || (t = !1), t) {
		var d;
		0 != n.getElementsByTagName("img")
			.length && (y = n.getElementsByTagName("img")[0], n.removeChild(y)), 0 == n.getElementsByTagName("canvas")
			.length ? (d = document.createElement("canvas"), n.append(d)) : d = n.getElementsByTagName("canvas")[0];
		var i = d.getContext("2d"),
			r = e.naturalWidth,
			s = e.naturalHeight;
		d.width = r, d.height = s, window.screen.width < 991 ? d.style.width = window.screen.width + "px" : r > window.screen.width && (d.style.width = r / 2 + "px"), d.style.padding = "10px";
		var l = a.split(".");
		l = l[0];
		for (var o = get_num(aid, l), m = parseInt(s % o), c = 0; c < o; c++) {
			var g = r,
				h = Math.floor(s / o),
				p = h * c,
				u = s - h * (c + 1) - m;
			0 == c ? h += m : p += m, i.drawImage(e, 0, u, g, h, 0, p, g, h)
		}
	} else {
		var y;
		0 == n.getElementsByTagName("img")
			.length ? (y = document.createElement("img"), n.append(y)) : y = n.getElementsByTagName("img")[0], y.src = e
	}
	n.style.display = "block"
}

function get_num(e, t) {
	var a = 10;
	if (e >= 268850) {
		var n = e + t;
		switch (n = (n = (n = md5(n))
				.substr(-1))
			.charCodeAt(), n %= 10) {
			case 0:
				a = 2;
				break;
			case 1:
				a = 4;
				break;
			case 2:
				a = 6;
				break;
			case 3:
				a = 8;
				break;
			case 4:
				a = 10;
				break;
			case 5:
				a = 12;
				break;
			case 6:
				a = 14;
				break;
			case 7:
				a = 16;
				break;
			case 8:
				a = 18;
				break;
			case 9:
				a = 20
		}
	}
	return a
}

看见第一个函数的函数名我们就知道应该去找谁了吧,我们直接在top文件夹中搜索scramble_image看看有没有东西。
在这里插入图片描述
你是真没让兄弟失望啊!我们直接点进去看看它传的参数具体是啥
这里面有四处调用了该方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
哥们也不管那么多了,直接打断点就完事了
在这里插入图片描述
通过对得到的数据进行查找,最后在当前页面的html里面找到了几个参数
在这里插入图片描述
但是我们还是不知道imgObj[0]传入的啥,这边建议直接控制台输出好吧。
在这里插入图片描述
这不就有了吗?
最终我们拿到了所有的参数,直接对刚刚解出来的代码进行分析,这里我就说结果,代码就在上面那么可以自己分析试试。
在这里插入图片描述
最后分析得出就是通过onImageLoaded方法来实现的,传入的参数e就是imgObj[0]。
它在这个方法里面生成了canvas标签,然后获取了图片的原始高宽,然后通过get_num方法计算出当前图片切片次数,最后通过for循环和canvas的drawImage绘制出最终的图片。
至此大功告成!!!


总结

做爬虫一定要有清晰的思路和逻辑,其次需要的是耐心,要敢于去尝试、去挖掘,不然只有败兴而归。当然F12、断点以及控制台我愿称之为最强!!!
就这样吧,下次见!!!期待你的关注!!!

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-28 11:10:38  更:2021-11-28 11:12:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:59:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码