也许还有其他简单的模块selenium,但本次并没有涉及到,等到以后有机会再去学习了解^_^。
一、查看请求的Headers
②看到一个POST请求sign_in,看一下它的Response
说明没错,就是这个Post请求;一般Post请求都会带一个FormData,检查后边,发现这个请求也不例外
但是这个参数不是常见的Key:Value格式,说明做了加密处理,那么我们现在就需要找到它的加密逻辑,然后模拟出这个参数。
二、加密方法
①加密函数
目前已知的就只有这个sign_in,在开发者模式的Source模块中,通过全局搜索CTRL+SHIFT+F搜索一下sign_in
只有这么一个js文件里边有sign_in,点进去之后,通过CTRL+F看看sign_in在这个文件中具体在哪。这里需要注意的是,网页为了节省资源,通常会省去语法格式,而将大量代码挤到一段中去,比如这样:
这样我们的开发就显得十分不便,好在我们可以通过左下方的一个按钮来还原它们的格式:
接着正文讲,我们在这个js文件中搜索到的sign_in有三个。可以通过调试+设置断点的方法判断哪个是我们需要的。这里就不贴调试的过程了。
运行到其中一个断点处,通过右边的Scope监视局部变量Local,可以发现这部分的局部变量包含了很多信息,可能以后会用到它。
信息有了相当于加密函数的部分参数就有了,那么这些参数是通过哪个函数被加密从而形成了FormData了呢?这里的加密方法的寻找,我参考了别人的方法:加密一般都是用encrypt之类的名字,所以可以直接搜索encrypt:
②加密函数的输入参数
接上文,如果我们把鼠标放在参数e上,
可以得到加密函数的输入参数,即下面这些参数用&连接构成的字符串:
captcha:动态输入的验证码——验证码的获取会在第三大部分的第②模块请求验证码中介绍,你也可以直接跳过去看。
signature:则是一个经过加密的属性,它和captcha都要通过额外编写函数来获取,不是可以直接得到的。但是获取方法并不难,下面介绍如何获取signature:
step1、在网页源码中,全局搜索signature,寻找看上去像进行加密的位置
step2、再调试一次,分别在该处和之前的加密函数encrypt处设置断点,观察encrypt的输入参数e的signature的值是否和该处signature的值相同,比较结果如下:
一模一样,看来这里就是给signature进行加密的地方了。这就有两个问题了——如何加密,对谁加密。
观察这部分代码,可以得到上边两个问题的答案:
a、如何加密——HMac加密模式,Hash函数:SHA-1
b、对谁加密——就是面代码中的a
a的内容呢?
可以看到,一共5项,分别是①“d1b964811afb40118a12068ff74a12f4”;②"password";③clientID;④"com.zhihu.web"⑤timestamp
所以我们在Python中编写对Signature的加密函数时,就是利用上面提到的五项参数和HMac函数进行的。这部分的代码如下:
defget_signature(self):#获取SignatureclientID=b'c3cef7c66a1843f8b3a9e6a1e3160e20'SK=b'd1b964811afb40118a12068ff74a12f4'h=hmac.new(SK,digestmod=hashlib.sha1)h.update(clientID)h.update(b'password')h.update(b'com.zhihu.web')h.update(self.timestamp.encode())returnh.hexdigest()
知道了加密函数的位置,我们就可以把参与加密的所有js方法都提取出来,放在一个html文件内执行就可以了。
向上寻找这个return所在函数的头,把这个函数的内容全部复制到一个JS文件中,总共400多行。
将上边的JS文件嵌入一个html文件中,放在script标签内即可。
这里贴出检验时的HTML文件和JS文件的写法:
HTML
获得参数