2020版python实现模拟登录知乎(包含自动过验证码) (上)

为什么要写这篇呢,因为最近想在知乎上采集一点数据(真的只是一点点~~!),但爬取的时候没有登录没有cookie值你是抓取不到的,这里可能有人会问,那直接从浏览器贴一下cookie值不就好了嘛,NO!NO!NO!,对于像我这样脱离了低级趣味的人,是不削这种做法的,什么叫懒匠精神? 这只有到达了一定的境界才会明白的,点一点手指,爬尽万千信息……

就是这种感觉……,闲话不多说,我们来整理下思路,额,飘了一下突然发现不知道从哪里下手了……不管那么多,先打开知乎网站看下:https://www.zhihu.com/

嗯,观察了一下,发现有几种模式登录,既然我们要做模拟自动登录,当然是用密码登录,接着操作下,发现在登录的过程中可能会出现2种形式的验证码:

1.中文验证码,找出倒立的文字

2.英文验证码

登录这个过程基本上就是输入账号,密码,验证码,然后提交,一般都是表单数据,我们打开开发者模式,跟踪一下登录接口的表单数据看下是什么样子的:

这是什么鬼,正常情况下应该是正常的表单参数格式,基本上登录就是根据这里的参数,模拟配置然后请求,请求成功后获得状态和cookie,然后保存cookie就可以为所欲为了,but……从上看这里的formdata貌似是一串加密的文本,这叫我从何入手,不管了先百度下,嘿嘿,革命的道路上永远不缺乏先驱的人民英雄,发现已经有志同道合的朋友已经对这个做了分析,我就他们基础上来实现吧,(为了尊重先驱的劳动成果我没有白嫖,我是一步一步跟踪的~~!),来,继续……打开调试器跟踪一下JS:

看了下,像这类的基本都是用类似webpack打包压缩了的,为了调试JS代码,我们打开:

然后看到JS都是混淆加密一堆一堆,脑壳痛,经常搞前端和爬虫的老玩家应该知道怎么格式化一下JS吧,算了,还是说一下,点这里,用红框了2次,怕你们看不到……

将近8万行代码……恕我的垃圾电脑有点带不动,根据上面我们可以看到登录的请求地址:

我们先复制下oauth/sign_in在js中搜索一下:

发现了这个接口,感觉应该没错,就是通过这里提交的请求,为了验证这个接口的正确性,我们在这里打一下断点,然后在登录界面乱输入一下账号再点一下登录:

不错,我们看下e,惊喜的发现这就是我在登录页面提交的账号密码,其它参数基本上都是固定的,除了timestamp和signature这个,timestamp这个简单看格式就是13位的时间戳,signature应该是个加密串,是怎么得到的这个参数呢,我们在JS搜索一下:signature,在app.js里面感觉没有找到想要的,我们在,(参考了下先驱的方法)这里搜一下,发现:

这个是hmac加密,如果做过加密算法的应该了解过,这里哈希算法是 sha1,密钥为 d1b964811afb40118a12068ff74a12f4,加密数据有四个,为 clientId、grantType、timestamp 和 source,好了,通过用上面的参数加密就能得到signature,用python实现hmac加密我们后面再讲,这里我们的目的是先模拟生成formdata数据,怎么得到formdata呢,接下来进行复杂的操作找出formdata的加密方法……,你可以通过跟踪调用函数慢慢的一步一步去找这个加密的方法,这里继续参考革命先驱的方法,先按下CTRL+SHIFT+F,不出以外会弹出一个,输入: encrypt, 因为一般加密的方法里都会用这个命名

果然下面搜到了有3个JS有这个方法名,我们先到main.app里查看下:

找到了这个方法,不知道是不是正确的,我们来断点调试下看看:

嗯,就是这个,站到先驱的肩膀上果然事半功倍,这个方法就是加密那一串表单数据的,那怎么转成python可用的呢,如果你用python来实现的话,我觉得没有那个有这个闲功夫来研究,而且它的算法有可能经常改变,简单的方法就是把这段JS方法考下来,然后用python的execjs的库来调用JS得到结果,但首先我们得将JS复制下来,在浏览器中调用看下是否可行,从这里开始:

向上找到这段JS:

我们将, function(module, exports, __webpack_require__) {……}这段JS复制下来,然后拷贝到一个JS文件中,然后去掉这个外壳,留下方法里的内容,我们去掉包含exports的参数,3个地方要删除,然后在下面直接加上参数调用:

在b的方法里的参数就是要加密的字符串,放入到html页面加载看一下打印结果:

奥利给,成功拿到了formdata加密后的值,距离成功不远了,那怎么在python中获取到这个值呢,通过下面方法:

#coding:utf-8
import execjs

with open('zh_encrypt.js', 'r', encoding='utf8') as f:
    js = execjs.compile(f.read())
    form_data='client_id=c3cef7c66a1843f8b3a9e6a1e3160e20&grant_type=password&timestamp=1589184275397&source=com.zhihu.web&signature=70f1cd2be0bd83f773ce3a96c413ffaa9be07a30&username=%2B861243324324&password=34343&captcha=&lang=en&utm_source=&ref_source=other_https%3A%2F%2Fwww.zhihu.com%2Fsignin%3Fnext%3D%252F'
    result=js.call('b', form_data)
    print(result)

来,这里我就不再一一的跟踪下去了,根据革命先驱的方法这里会遇到一些问题,对于一般的革命同胞来说,下面的问题可能是致命的,还好,我们继续踏着革命先驱的肩膀前行,我把下面遇到的问题罗列下:

首先不出意外会出现这个js第412行(相对于我的文件来说):

  改成: ,因为没有浏览器,是没有window之类的对象的

接着在运行一下会出现:

atob这个方法在python里是没有的,这个方法的用途就是解密通过base64加密后的字符串,先搜到atob的所在位置,将:

替换成:

革命先驱踩过的坑我们就不踩了,这里的意思是在浏览器中base64加密的是 binary 编码,这里解密也要用 binary 编码,来接着运行下,打印一下:

完美,至此模拟登录知乎的第一步算是完成了,我们得到了加密后的formdata,再次感谢永不停步的革命先驱……

认真的时光总是过得这么快……下篇接着会讲怎样实现登录以及怎样自动过验证码,感谢大家的耐心阅读,先去敲代码了……(点不点赞无所谓啦,虽然我的心不是这么想的~~!)

额……关于源码呢,白嫖兄弟们可以给我留言,可以加公众号回复:知乎 

关注公众号,实现不一样的自我

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值