学了python不知干啥?爬爬虫!(6)爱词霸翻译(内容详尽,从打开网页手把手完成JS逆向并写出代码)
多线程批量翻译
合理爬取,不恶意扩大站点压力
本文章仅作示例,请勿用作非法用途
前言
前几篇教程的爬取,我们一直局限于静态网站,且请求仅限于get。但在实际的开发过程中,动态内容才往往是爬取的核心。在本节内容中,我将带你一步步分析爱词霸的翻译结果获取过程,并伪装请求实现单词翻译。
本篇内容为本人原创,转载请注明!
请注意,本篇内容仅限于学习交流,切勿用于商业用途!
分析
网络加载过程
首先打开爱词霸,并使用 F12 打开开发者工具 【此处使用浏览器为Edge,如使用其他浏览器请参照对应教程打开此界面】 。
为了动态分析翻译过程,我们需要切换到 网络(Network) 标签页
输入任意单词,点击翻译按钮,你将会看到如下请求结果:
这就是动态翻译的请求。在此条请求上右键-复制链接地址
得到如下结果
1 | https://ifanyi.iciba.com/index.php?c=trans&m=fy&client=6&auth_user=key_ciba&sign=0020c1fc11e96d3a |
目前的链接有许多参数尚未明确,我们先留着,之后再做分析。
切换到预览标签页并展开结果,我们惊喜地发现,翻译结果就藏在对应的json中。
目标就是模拟这个请求,那么下一步我们需要弄清楚这里面的参数究竟各代表什么。
切换到标头页,在这里我们可以查看详细的请求头
可以看到,除了明显的get请求外,该请求还携带有表单参数。分析字段不难发现,post的表单带有此次翻译的单词信息。其中,from和to分别是源语言和目标语言,q即为翻译的单词。
我们需要弄清楚其他参数是什么意思。此处采用对比的方法。
再次翻译另一个单词,得到第二组请求地址和请求头
1 | https://ifanyi.iciba.com/index.php?c=trans&m=fy&client=6&auth_user=key_ciba&sign=09467500f66fb4a7 |
上下对比可知,两次请求的url中,仅有sign参数发生改变。可以猜测正是此参数起到加密作用。下一步我们就需要搞清楚,这个参数是怎么来的。
我们进入重头戏:源码分析!
JS源码分析
现在我们的目标是找sign,那么最直白的思路就很显然了:看看源代码那些地方出现了”sign”,那些就是比较可疑的地方。
切换到源代码标签,使用快捷键Ctrl+Shift+F或按下图找到全局搜索面板
先尝试一下直接搜索sign
得到了9个结果,先进入第一个排查。
使用“优质打印”格式化代码以便于后面的分析。
使用Ctrl+F打开页内搜索,尝试查找“sign”
但是结果很不理想,有相当大的一部分是关于assign的,不利于结果的分析。
我们大概推测,sign在代码执行过程中应该是某个对象的参数。因此改用”\.sign”重新搜索
逐个排查,发现这几个signature有较大概率是我们的目标。
是不是呢?验证一下就知道了。
在源代码左侧的行号旁单击鼠标打上断点,程序就会在运行到此处时暂停。
重新点击翻译按钮,得到运行结果
观察上图,从变量的值我们可以看到,在这行代码执行前就已经产生了sign
不难看出,变量r可能就是封装好的请求内容,而e则是对应链接。
那么我们的关注点就在变量e上,而变量e已经带有了对应的sign。于是我们从旁边的调用堆栈标签找到在断点执行位置的上一处,观察此处的代码和变量值
变量r的值引起了我们的注意,这一串字符非常符合刚刚看到的sign的特征。究竟是不是,我们让代码恢复执行,看看结果。
最终的请求url中的sign参数正是此处的r!
于是为r赋值的这一行代码就非常重要了,摘录如下:
1 | takeResult: function(e) { |
从这里的js代码可得知,r是调用c()函数得到的结果,传入的参数是一个固定字符串 “6key_cibaifanyicjbysdlove1”
再拼接上翻译的单词,之后调用 replace(/(^\s*)|(\s*$)/g, ""))
的结果。下一步就是看看,这个c()究竟是个什么东西?
切换标签为控制台页,输入c()
发现它返回的是一个函数,点击上面的输出结果,可以跳转到对应的源代码位置
这是一个陌生的函数。进行到这一步,让我们回顾一下,我们输入的参数是明文,出来的却是英文字符组成的字符串。我们可以猜测,此处的函数作用就是对参数进行某种加密或哈希算法。
翻阅这个js文件,可以发现大量的位运算操作,这正是加密中常用的操作。因此我们可以就此猜测,这个文件就是一个库文件,功能就是实现常见的字符串加密算法。
到这里思路换了个方向。我们不妨暂时跳出分析代码的过程,看看JS中有没有这样的库存在。
搜索的结果几乎全部指向了CryptoJS这个第三方库,那我们去Github看看它的源代码
尝试搜索刚刚代码中出现的 _createHelper
字段。
在 core.js
下,我们发现了这一段:
与刚才的
一模一样!!!
寻找具体算法
简单搜索得知,CryptoJS提供了种类丰富的加密算法。要找到此处用的是哪一种就有很多办法。这里我们选择:黑箱理论。
黑箱理论,是指对特定的系统开展研究时,人们把系统作为一个看不透的黑色箱子,研究中不涉及系统内部的结构和相互关系,仅从其输入输出的特点了解该系统规律,用黑箱方法得到的对一个系统规律的认识。
寻找一个特定的输入:
在调试模式下选中生成参数的部分代码,就可以看到此次运行的结果
上面这一次的运行结果如下:
随便打开一个用于加密的网站,经过不断尝试,在尝试到MD5的时候,得到了一模一样的结果:
1 | 18dc7242de5f73cae3b299a6c8eba326 |
如此就确定了加密方式:MD5!
一切就绪,下一步自然就是编写代码啦!开干!
代码编写
上面分析得很到位了,每一个参数都给了详尽的解释,此处就不再赘述。参见代码和注释即可。
完整代码
1 | """ |