Python爬虫高级之JS渗透登录新浪微博

485次阅读
没有评论

小伙伴们看到标题可能会想,我能直接自己登陆把登陆后的cookie复制下来加到自定义的请求头里面不香嘛,为什么非要用python模拟登录的过程?如果我们是长期爬取数据,比如每天早上中午和晚上定时爬取新浪,那么,这个方法对我们来讲可能就非常的不方便了,因为我们一直都在重复的做登录复制的劳动,这对我们程序员甚至是普通人来讲都是很不友好的。

所以,今天我给大家带来用python模拟登录新浪微博的过程。
Python爬虫高级之JS渗透登录新浪微博

一、JS渗透爬虫准备工作

在介绍代码之前,我先说一下代码中用到的库。

1.rsa(是一个非对称加密算法,需要pip安装一下)
2.Requests(可以说,只要有爬虫的地方大多数都有它)
3.base64(加密算法)python内置的
4.time(时间模块)
5.json(处理字符串的)
6.binascii(这个是处理16进制数的,可以将前面多余的显示十六进制信息的符号去掉)

1.工具介绍

然后我们用到的抓包工具,Fiddler 4。这款工具,在爬虫这里来讲,尤其是涉及到了高级和js渗透,没有这个工具肯定是不行的。

由于在这里我们还涉及到js渗透,所以推荐使用的浏览器是谷歌浏览器,我们的例子也是用谷歌浏览器实现的。现在,我必须先介绍一下js渗透的基本思想和方法。

Js渗透,故名思意,就是利用js代码,从而分析出网页中的参数到底是怎么来的,从而模拟关键参数构造的过程,从而可以自己构造数据包,达到我们想要达到的目的。

那到底如何渗透呢?我们先来了解一下我们的工具!

2.谷歌浏览器
Python爬虫高级之JS渗透登录新浪微博
首先,我们看第一个两个箭头所指的Elements,在元素这一栏里面,右边有一个事件,也就是EventListeners,点击这个栏目,我们可以看到click这个字段,我们点击它,会看到出现了几个栏目,这个就是我们触发调试的关键,在click中,只要我们的鼠标点击一次,就相当于出发了一个焦点,每触发一个焦点,就会触发调试,当然,这个是需要我们打断点的,至于怎么打断点,我在下面会讲到。在触发的焦点中,我们需要的是登录这个按钮的这个触发点,click,因为这个很关键,如图:
Python爬虫高级之JS渗透登录新浪微博
要唤出我们需要的点击事件,我们需要用如下图所示的小鼠标,点击它,然后再点击上面的登录按钮,这样,在click中就能够跳出我们想要的触发事件,如图:
Python爬虫高级之JS渗透登录新浪微博
Console这个模块。这个模块非常的有意思,它是我们看js内部代码的关键所在,等等我们就会演示。

Source:这个模块就是用来看js代码的,这里我们点击 source,然后看一下右边的栏目:
Python爬虫高级之JS渗透登录新浪微博
箭头从右至左分别是,调试的暂停,下一步,进入到改行代码的函数中,以及跳出函数继续执行。这个是我们调试的另一个关键的模块。我们可以发现,上面图片中的js代码根本不是人看的,当然这个不要紧,我们可以注意到,图片左下角有一个{},点击它,就可以让代码变成人可读的样子。

Network:这个是chrome自带的抓包模块,在这里面,我们可以抓到每个请求的http包。使用方法就是如图:
Python爬虫高级之JS渗透登录新浪微博
左边的箭头是停止抓包,右边的箭头是清除抓到的包。点击图中的Initiator,可以进入到该包的js模块中,这个也是我们等等会重点用到的。

3.Fiddler

我最后再介绍一下fiddler这个软件,这个软件在网上可以下载,是免费的。

它是一款在osi七层模型中抓取应用层上面http协议的软件,它在爬虫中的地位也是很高的,也很重要。
Python爬虫高级之JS渗透登录新浪微博
我们可以看到,上面就是协议包,而哪个capturing就是正在抓取的意思,我们可以再抓取到我们想要的数据包的时候,再点击它,将抓包停止。
Python爬虫高级之JS渗透登录新浪微博
这里就是我们需要看参数的地方,非常的关键,因为我们的参数就是从这里观察到的。

如果显示不了文本就点击黄色的那一栏,这样就可以转码了。当然我们还需要善于利用查找关键字来定位我们的参数在哪里。

大家一定要注意,全局搜索的用处是很大的,平常大家的搜索技能在爬虫中可以更加充分的发挥作用。

二、微博实战

1.Fiddler抓包应用

现在让我们看看到底怎么样实现微博登录的吧。

第一步,我们打开新浪的网站,网站的url是:https://weibo.com/

然后,我们打开fillder这个抓包工具,记住,我们先输入账号和正确的密码,点击登录,然后等到登陆后的页面出来后,我们停止抓包,我们可以看到如下的数据包:

当然,一开始使用fiddler可能会出现读者抓不到包的情况,这个也有解决办法:我们点击左上角的Tools,然后点击里面的Options选项,在跳出来的框中,点击HTTPS,然后点击Actions,点击跳出来的第一个选项,然后按yes,之后一直同意就好了,接下来我们就能抓包了。
Python爬虫高级之JS渗透登录新浪微博
我们发现,在数据包中有一个带login的url,这个我断定应该是一个登录请求,那是不是说,只要构造这个包里面的参数,就可以进行模拟登录了呢?

现在,我们来看一下这个包里面具体的数据:
Python爬虫高级之JS渗透登录新浪微博
在这个数据包中,我们能看到有很多的参数,但是参数我们都说分成固定的参数和动态的参数,固定的参数,我们只需要复制黏贴就行,但是,动态参数是需要我们模拟的,所以,我们需要在这些参数中,找到动态的参数。找法就是多发送几次请求用错误的密码,正确的密码去试,然后对比这几次抓到的同一个包。这里我们把这个步骤留给读者自己验证,现在我来说结论,我发现,nonce,sp,rsakv,servertime这几个参数是会变的,其他参数是固定的。那么,接下来,我们就是要模拟这些参数,搞清楚它们是怎么来的。

首先,我们利用查找功能,查找nonce的出处,如图:
Python爬虫高级之JS渗透登录新浪微博
这个软件会将关键字出现的地方标黄。

我们点击prelogin这个包,发现在它的数据体里面出现了nonce:
Python爬虫高级之JS渗透登录新浪微博
以及rsakv也出现在这个里面。从这里,我们可以得出结论,是不是我们只要构造这里面的参数,就可以拿到这两个动态参数呢?经过实践,这个结论确实是正确的。

2.代码构造参数,抓取第一部分的关键信息

接下来就是代码的实现:

import requests import time import base64 import json,rsa,binascii username = '15952081***'# 手机号 # 这个是预登录 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36', }# 构造请求头 username = base64.b64encode(username.encode()) # 用户名加密 sess = requests.session() sess.headers = headers urls = 'https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=MTU4MDE3MzY2NDc%3D&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_=1582460772360' # 通过抓包获得的url params = { 'su':username, 'rsakt':'mod', 'entry':'weibo', 'client':'ssologin.js(v1.4.19)', 'checkpin':1, 'callback':'sinaSSOController.preloginCallBack', '_':int(time.time()),

} r = sess.get(url=urls,params = params) print(r.text)

既然我们已经知道,它是在prelogin这个包中,那么接下来,我们必须开始js渗透。

首先我们要刷新一下新浪的界面,然后把network里面的数据包全部清除,点击账号的输入框,输入自己的账号,在用鼠标点击密码框后,我们发现,在network上面就跳出来了我们想要的包,prelogin。
Python爬虫高级之JS渗透登录新浪微博
下一步,我们要点击initiator中,prelogin对应的哪个连接,进入js代码中,然后再按左下角的大括号整理代码格式。当进入到代码后,我们按下ctrl+f在跳出的搜索栏中打入su然后回车,我们就很快发现了su的加密模式:
Python爬虫高级之JS渗透登录新浪微博
就是base64加密。所以我们引入了base64这个模块,构造su参数,具体的就在代码中体现了。接下来,我们就是要请求这个prelogin页面,从而获取里面的文本,因为我们需要里面的除sp以外的动态参数。

请求后我们打印r.text,获得到的数据是这样的:
Python爬虫高级之JS渗透登录新浪微博
我们可以发现,上面的参数有很多是我们确实需要的,这也就意味着我么的渗透第一步成功了。

三、关键参数sp

我们可以发现,确实都在里面了。现在,我们只需要用正则,匹配大括号及其里面的东西,然后用json重载一下(loads),文本就能和字典一样操作了。

接下来,就是要破解sp这个参数到底是怎么来的了。

下面,就到了之前介绍的环节了。

首先,我们要到Elements里面的Event Listeners中,点击click,然后再点击进入js页面,如图:
Python爬虫高级之JS渗透登录新浪微博
点击这个链接,这样就能进入js代码中。然后,再js中按下Ctrl+f输入rsa,为什么不输入sp呢?因为输入sp有很多不是我们要的东西也会涉及进来,会导致搜索的繁琐性变得更大,然而,rsa是一个非对称加密算法,在之前的prelogin中我们可以找到pubkey这个字段,从中我们可以断定,sp和rsa加密算法紧密相连,从而搜索rsa来找到sp的具体实现位置。

进入js后,我们发现再2825行有一个蓝色的箭头,如果没有,就点击2825这个数字,就有了,这个就是我们说的断点。断点设定完之后,我们需要把鼠标移动到登录框,在框的范围内点击一下,这个叫做触发一次事件,这样就能进入断点调试模式。

我们之前已经在搜索栏中打入了rsa所以,在没有匹配到rsa之前,我们必须不停的按下一步,途中会跳过很多js文件,这个是正常的,我们只需要关注我们需要的js代码即可。

当我们匹配到rsa后,那么就说明,sp肯定也在这里面,此时我们再把rsa换成sp,我们就很快发现了sp的所在位置,如图:
Python爬虫高级之JS渗透登录新浪微博
我们发现,b赋给了sp,而b又是啥呢,我们发现b是f的返回值,而且,由于我们是rsa加密,所以是if语句下面执行的代码。再观察,我们发现,首先是f设置了公钥,然后呢,再利用公钥给b加了密,里面还添加了其他的参数,而这些参数,刚好是我们能获取到的。公钥的设置,以及加密的过程涉及到rsa算法,这个读者可以看看这个url下面的文章,从而更好地理解下面的操作。

https://blog.csdn.net/gao131360144/article/details/79966094

由于setPublic中,第一个参数是固定的,而第二个中有一个10001,读者到这里可不能就这么认为就是十进制10001这个数,如果这样,那就太不严谨了,因为,这个数可能是十六进制,也可能是二进制,甚至是17进制;只要开发者胆子大,啥进制都能设置,这也是此渗透的难点所在。那我们如何去判断,这个参数到底是什么进制呢?这个时候就要用到控制台(console)了。刚刚我们介绍过控制台。在js中,这个控制台可以把自己的代码给打出来,小伙伴们到这里不要惊奇,这个js这么随意的嘛?确实,js随意起来连自己都卖。

1.断点调试

首先,我们要在我们想看的f这个对象这里打上断点,让代码执行到这,如下图所示:
Python爬虫高级之JS渗透登录新浪微博
然后,我们点击调试按钮中的像播放键▶ 这样的一个符号,停止调试,接下来再点击登录按钮,触发事件,启动调试,这样,我们就能够停在现在我们设置的断电这里,要注意的是,密码和账号都要输入,密码可以不正确,因为这个只是调试而已。

如图:
Python爬虫高级之JS渗透登录新浪微博
接下来我们点下一步,直到过了f这一行。接下来,我们点击控制台,输入f.setPublic()按回车后我们发现,源代码出来了,如图:
Python爬虫高级之JS渗透登录新浪微博
我们可以发现,这个10001对应的是16进制,而不是十进制。
接下来,最后一个问题就是b到底是啥?

很简单,在控制台输入b回车,大家就会惊奇的发现,是自己的密码。

在知道了sp的来龙去脉之后,我们开始构造sp的加密函数了:

def encrypt_password(password,pubkey_N,servertime,nonce): public_key = rsa.PublicKey(int(pubkey_N,16),int('10001',16)) message = str(servertime)+'\t'+nonce+'\n'+password r_byte = rsa.encrypt(message.encode(),public_key)# 加密参数,是二进制的形式 return binascii.b2a_hex(r_byte).decode() # 改成十六进制

其中,binascii就是用来将数据从十进制转换成十六进制的,最后的decode就是将数据从二进制编码变成字符串的形式然后传送给服务器。

2.伪造请求

函数构造完后,我们就可以构造最终的登录请求了:

paramss = { 'entry':'weibo', 'gateway':1, 'from':'', 'savestate':7, 'qrcode_flag':'false', 'useticket':1, 'pagerefer':'https://login.sina.com.cn/crossdomain2.php?action=logout&r=https%3A%2F%2Fpassport.weibo.com%2Fwbsso%2Flogout%3Fr%3Dhttps%253A%252F%252Fweibo.com%26returntype%3D1', 'vsnf':1, 'su':username, # 用户名的base64加密 'service':'miniblog', 'servertime':json_text['servertime'], 'nonce':json_text['nonce'], 'pwencode':'rsa2', 'rsakv':json_text['rsakv'], 'sp':encrypt_password('991123',json_text['pubkey'],json_text['servertime'],json_text['nonce']), 'sr':'1920*1080', 'encoding':'UTF-8', 'prelt':'145', 'url':'https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack', 'returntype':'META' }

url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)' r = sess.post(url,data=paramss)

3.url的进一步分析

在提交完数据后,我们其实并没有登录成功,原因就在于参数提交后的在真正页面出来之前的请求,我们从抓包的软件中可以发现,这些请求,是用来设置cookie的,如图:
Python爬虫高级之JS渗透登录新浪微博
所以,我们再发送登录请求后,还需要继续模拟四次请求,才能让服务器帮我们设置coookie,完成登录。这些网址怎么来?总不可能一个个手打上去吧,当然,我们写代码也不是为了手打网址,这些网址就隐藏在/crossdomain2.php?这个包中。我们只需要将这四个网址中的任意一个网址的一部分复制查询一下,就能够很快的定位这四个网址的来源了,如图:
Python爬虫高级之JS渗透登录新浪微博
那我们怎么获取这个页面呢?我们继续网上看,发现再我们刚刚请求的login页面中的文本里面,有这个页面的地址,如图:
Python爬虫高级之JS渗透登录新浪微博
4.再次伪造请求,设置cookie

于是,我们的思路就来了,首先,构造参数发送请求,然后呢,再请求这个login页面,用正则将里面的url匹配出来。然后再请求一次,把里面的四个网址匹配下来,最后写个循环,请求这四个网址。

5.查询自己的用户名,检查是否登录成功

最后我们请求https://weibo.com/u/7382963711/home?wvr=5&lf=reg 这个网址,打印一下它的html文本,看看自己的用户名在不在html文本中,如果在的话,就说明我们的模拟登录成功了。现在,附上剩下的代码:

url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)' r = sess.post(url,data=paramss) r.encoding='gbk' url_next = re.search(r'location.replace\("(.*?)"\)',r.text).group(1) r_1 = sess.get(url=url_next) # print(r_1.text) url_list = re.search(r'"arrURL":\[(.*?)\]',r_1.text).group(1) url_list = url_list.split(',') # print(url_list) for i in url_list: urls = i.replace('\\','') urls=''.join(urls.split('"')) r = sess.get(url=urls)

r = sess.get('https://weibo.com/u/7382963711/home?wvr=5&lf=reg') print(r.text)

到此,我们的模拟登录就完成了。感谢大家的观看和学习。

更多干货内容,欢迎关注公众号:知了python

神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试

相关文章:

版权声明:Python教程2022-10-24发表,共计7943字。
新手QQ群:570568346,欢迎进群讨论 Python51学习