怕有的人不知道JS逆向是个什么东西,这里大概解释一下。在爬虫分析网站过程中可能会碰到一些数据没法直接通过网站的response得到,而要构造参数访问网站,就是向对方服务器发送请求,然后模拟网站获取数据,而其中的构造参数这一步骤就是JS逆向,有好些参数是通过网站后台的JavaScript生成的,我们要做的就是找出后台参数生成的原理。
不管听懂与否,还是看接下来的分析吧,在实战中学习知识效率是最高的。
一、分析环节
1、本次爬虫的目标是百度翻译,因此我们进入到百度翻译网站,一波常规操作。打开开发者工具,选中“XHR”,然后在翻译框输入任意文字,观察新增的数据包。
可以看到红色方框中的数据就是我们在翻译框中输入的数据。因此,整个表单数据就是我们这次分析的目的,构造出这些表单数据,然后通过post请求访问对应的链接,即可获得想要的数据。首先我们需要观察哪些数据是动态变化的,这也是需要我们重点关注的。经过分析可以发现sign是需要解密的参数。
2、找到动态变化的数据后,我们就需要在网页源代码中寻找包含这个“sign”参数的代码,在这里,可以直接搜索“sign”这个关键字参数,也可以搜索这个请求连接的片段。
在这里可以看到,直接使用关键字参数进行搜索查询到了三个文件,而使用请求连接片段则只有一个符合条件的文件。由此,我们也可以确定具体的逻辑就是在“index_5bbbfa0.js”文件中,直接点进去这个脚本,然后将代码格式化一下,以便于我们进行代码查找分析。
3、在该文件中,我们还需要进一步找到我们需要的参数,直接搜索即可,然后就可以定位到我们需要的参数位置。
接下来,在此处打上断点,然后刷新网页,确定数据的加密是由此处代码实现的。
可以看到,目前的代码停在了sign这里,也就是说,sign就是在此处生成的,接下来,我们就可以进入到具体的函数内部,红线下方的函数就是生成sign参数的js代码,找到它之后,我们可以将其复制到js文件当中,然后就可以写具体的代码了。
二、代码调试
import requests
import execjs
class BaiduTranslater:
def __init__(self, sources):
self.sources = sources #输入翻译的内容
self.url = 'https://fanyi.baidu.com/v2transapi?from=zh&to=en' #访问网站
self.headers = { #请求头
'origin': 'https: // fanyi.baidu.com',
'referer': 'https: // fanyi.baidu.com /?aldtype = 16047',
'user - agent': #自行添加,
'cookie': #自行添加
}
def data_creater(self): #生成data参数表
with open("code.js", 'r')as f: #调用从网站上复制下来的js脚本
content = execjs.compile(f.read()) #编译脚本
sign = content.call("e", self.sources) #得到sign值
self.data = {
'from': 'zh',
'to': 'en',
'query': self.sources,
'transtype': 'translang',
'simple_means_flag': 3,
'sign': sign,
'token': '1c65e5489209deafd9e0302de91a0010', #系统常量
'domain': 'common'
}
def crawler(self):
self.data_creater() #先生成data
res = requests.post(self.url, data=self.data, headers=self.headers)
res.encoding = 'utf-8'
print(res.json()['trans_result']['data'][0]['dst']) #对应翻译结果
if __name__ == '__main__':
while True:
str_input = input("请输入单词:")
if str_input == 'q':
break
baidu = BaiduTranslater(str_input) #实例化百度翻译类
baidu.crawler() #调用函数进行翻译
其中有必要一提的就是execjs需要额外安装,可以在cmd中输入“pip install PyExecJS”进行安装。
JS脚本初步为下图所示,而翻译的结果可以根据得到的json自行提取想要的数据,这里只写简单的翻译结果的提取。
代码有些长我就收起了一些代码,这里千万注意js代码的结构不要出错,认清大括号的匹配是否正确。
接下来直接运行代码,发现是会报错的。如下图
报错了没事,不要慌,只是js文件里的 i 没有被定义,编译的时候找不到 i 值而已。只要回到之前的网站界面继续分析就好了。回到函数内部,然后一步步往下执行,可以看到i的值。
可以很清楚看到 i 的值就是这个常量,然后,将i这个常量添加到js代码中,
再次运行程序,发现又出现了新错误,没事我们继续分析。这里毕竟是用人家的js代码,而不是看懂js代码实现sign的原理自己写python代码,所以要屈从于网站脚本,如果你有JS基础可以选择自己用python写原理,不过这种方法较为耗时就是了。我们还是按部就班,一步一步地往下运行。
显然这就是我们需要的n ,而n是一个函数,我们将红框中的代码复制进code.js中,然后运行程序。
终于成功了!!!
三、总结
从中你也可能窥探到了JS逆向真正麻烦的地方就是在网站上调试,寻找想要的代码和参数的构成。这是个需要耐心和时间的过程,说实话是真的需要毅力的。初学者可以在网上找找近期的视频跟着学习,然后自己动手实操,写的多了,就会觉得比较容易。