写在前面
现在前端页面为了防止爬虫恶意爬取数据,多多少少会对数据进行加密,有的是重新编码再解码,有的是用字体来表示纯文本,还有用图片的。如果直接爬取,由于没有js动态加载,因此都是原始的加密后的数据,需要通过一定手段还原为可读数据。正所谓只有魔法才能打败魔法,也只有代码才能打败代码。还是一句话,只要是前端js加密的内容,理论上都是可以通过js来反向还原数据的,只不过大多数js都经过混淆,可读性差,需要不断打断点调试,确定核心的解密函数。本来想直接爬取的,结果发现名称都是被加密过的,查看源代码后,发现加密过程简单,非常适合入门。
解密过程分析
网页显示的是一行行的标题内容,是通过ul li
标签实现的,爬取不是难事,但是标题不是直接的文本,而是下面这样的内容,显然是js动态生成标题的。
<li>[03-07]
<a href="/movie.php?id=9523175675421954" target='_blank'>
<script type="text/javascript">
document.write(d('OTHlkYblk6Xns7vliJcwMTYt6YWS5bqX5YG35oOFNFPlupfnvo7lpbPplIDllK7pq5jmuIXml6DmsLTljbDlrozmlbTniYg='));
</script>
</a>
</li>
既然是前端解密,那么就好办了,找到d
函数就可以了,这里使用使用Chrome的F12功能,打断点找到函数调用过程即可,找到的d
函数是孤立的,没有与其他函数嵌套,所以单独分析d
函数即可。
function d(input){
rv = window.atob(input);
rv = escape(rv);
rv = decodeURIComponent(rv);
return rv;
}
虽然d
函数中有三个其它函数,但都是js自带的函数,也就是说只要查阅这三个函数的功能即可。window.atob
是用于将编码后的Base64字符串转为ASCII字符串。效果如下:
var str = 'javascript';
window.btoa(str) // 编码结果 "amF2YXNjcmlwdA=="
window.atob("amF2YXNjcmlwdA==") // 解码结果 "javascript"
escape
函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串。该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . / 。其他所有的字符都会被转义序列替换。
escape("JavaScript_ _脚本语言@!");
"JavaScript_%20_%u811A%u672C%u8BED%u8A00@%21"
decodeURIComponent
函数可对encodeURIComponent
函数编码后的 URI 进行解码。
我们尝试将数据解码后看一下,可以得到如下结果:
// 再也不用担心被显示敏感词了。
d("OTHlkYblk6Xns7vliJcwMTYt6YWS5bqX5YG35oOFNFPlupfnvo7lpbPplIDllK7pq5jmuIXml6DmsLTljbDlrozmlbTniYg=")
"91呆哥系列016-酒店偷情4S店美女销售高清无水印完整版"
在弄懂了d
函数的实现过程后,还可以写出其逆过程
function r(input){
res = encodeURIComponent(input);
res = unescape(res);
res = window.btoa(res);
return res;
}
Python实现
import base64
base64.b64decode(input).decode()
from urllib.request import unquote
unquote(base64.b64decode(input).decode()) // 其实不要这步已经可以得到结果了。