2020.10.20利用POST请求模拟登录知乎ShineLe

也许还有其他简单的模块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

Title

获得参数

T.js

用浏览器打开,就可以看到加密的字符串也就是发送的FormData了。它与我们之前RequestHeader中的FormData的值相同(这里由于我是第二天做的,所以和前一天的FormData不同)。

搞完这个后,我们就可以继续使用Python来操作了,因为加密方法格式化后有400多行,实在太多,也全都是混淆,不太可能用Python一个一个实现,所以这里选择用Python的execjs来直接执行JavaScript代码从而获得FormData,简单且方便。

不过要注意的是,前边我们写的JS文件是用来嵌入HTML并在网页中打开的,所以给这个JS文件提供的是Web环境。但是想在Python中通过execjs执行的JS是需要Node环境,所以需要对之前的JS代码稍加修改。

修改一、开头添加抬头

constjsdom=require("jsdom");const{JSDOM}=jsdom;constdom=newJSDOM(`

Helloworld

`);window=dom.window;document=window.document;修改二、atob=>window.atob

之后运行一下JS检查一下结果(这里我是在Pycharm中执行的JS文件,环境是NodeJS。在这个JS文件最后一行用console.log(b("client=..."))代替我们之前写的document.write将FormData输出到命令行检查)

可见Node环境下配置正确,运行结果正确。

这就是提取的加密函数并且进行加密的部分。

另外还有个问题我们一直忽略了,那就是加密函数的参数问题,是的,光有加密函数还不行,你得知道它是对哪些参数进行了加密才得到了最后的FormData;换言之,我们现在只是知道了输入-处理-输出中的处理和输出部分,接下来,我们要看看输入的参数是哪些。

为什么我把输入放在最后说呢?是因为我们有个取巧的方法帮助我们获得这些参数,使我可以用较短的篇幅来说明有哪些参数。

①还是回到我们之前的encrypt部分的代码

①请求头headers信息

必须要有三个要素:User-Agent、Content-Type、x-zse-83

headers.update({'content-type':'application/x-www-form-urlencoded','x-zse-83':'3_2.0','x-xsrftoken':self._get_xsrf(),'User-Agent':'Mozilla/5.0(WindowsNT6.3;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/63.0.3239.132Safari/537.36'})不带Content-Type,会出现错误:

Missingargumentgrant_type

不带x-zse-83,会出现错误:

请求参数异常,请升级客户端后重试

User-Agent就不用说了

②请求验证码

此外,上述三次请求的验证码地址的请求方法都是不同的,从前到后分别是GET、PUT和POST,且这三次请求的内容都是通过json编码,可以在请求之后通过json()方法解码为dict类型的对象。

cptcha验证码,是通过GET请求单独的API接口返回是否需要验证码(无论是否需要,都要请求一次),如果是True则需要再次PUT请求获取图片的base64编码。

知乎验证码有两种形式,一种是点击倒立文字,另一种是输入英文字符串。区别在于传入的参数lang是cn还是en。这里只实现第二种验证方式。

四、补充内容

a、验证验证码

验证验证码时的请求头只需要有User-Agent字段就可以了。

b、请求的所有阶段都要带上Cookie

如果不带Cookie请求或者请求顺序不一样就有可能返回错误:

{"error":{"message":"缺少验证码票据","code":120002,"name":"ERR_CAPSION_TICKET_NOT_FOUND"}}

THE END
1.能让您学习工作生活提升1000倍效率的绝对实用工具——潇儿常用2. 豌豆荚一览-在一个应用里刷你关心应用的内容(高效率阅读新闻资讯娱乐八卦) 作者是 联翩科技 https://appsto.re/cn/jnT07.i 2. 手机猪八戒—店铺装修,logo设计,网站开发,微商创业助手 作者是 Zhubajie.com https://appsto.re/cn/1YWLJ.i 3. 知乎 作者是 Zhihu Inc https://www.jianshu.com/p/ba59b965b7a7
2.推荐一波对你来说,非常有用的网站,记得收藏来个网推荐一波对你来说,非常有用的网站,记得收藏 # 学习相关 知乎:www.zhihu.com TED(最优质的演讲):https://www.ted.com/ 谷粉学术: https://gfsoso.99lb.net/scholar.html 大学资源网:http://www.dxzy163.com/ 简答题:http://www.jiandati.com/https://blog.csdn.net/weixin_42542426/article/details/105028019
3.知乎知乎,中文互联网高质量的问答社区和创作者聚集的原创内容平台,于 2011 年 1 月正式上线,以「让人们更好的分享知识、经验和见解,找到自己的解答」为品牌使命。知乎凭借认真、专业、友善的社区氛围、独特的产品机制以及结构化和易获得的优质内容,聚集了中文互联网科技、http://www-quic.zhihu.com/