文章目录
写在前面
原计划这篇博客写在6月1日,没想到竟然由于写pandas给耽误了
查看pandas系列请移步
课程 | 链接 |
---|---|
Python数据分析库之pandas,你该这么学!No.1 | https://dream.blog.csdn.net/article/details/90169175 |
看一篇,学一篇,今日份的pandas,你该这么学!No.2 | https://dream.blog.csdn.net/article/details/90199748 |
点开,看一段,你就会喜欢上学习pandas,你该这么学!No.3 | https://dream.blog.csdn.net/article/details/90212197 |
学习也可以有趣,喜欢上pandas,你该这么学!No.4 | https://dream.blog.csdn.net/article/details/90229919 |
“戏精少女”的pandas学习之路,你该这么学!No.5 | https://dream.blog.csdn.net/article/details/90241420 |
对不起,给pandas配表情包太难了,pandas你该这么学,No.6 | https://dream.blog.csdn.net/article/details/90303728 |
大周末的不休息,继续学习pandas吧,pandas你该这么学,No.7 | https://dream.blog.csdn.net/article/details/90340844 |
周一不睡觉,也要把pandas groupy 肝完,你该这么学,No.8 | https://dream.blog.csdn.net/article/details/90379695 |
破周三,前不着村后不着店的,只好学pandas了,你该这么学,No.9 | https://dream.blog.csdn.net/article/details/90445734 |
学习pandas apply方法,看这一篇就够了,你该这么学,No.10 | https://dream.blog.csdn.net/article/details/90665922 |
pandas越来越难学,只能自己找趣味了,你该这么学,No.11 | https://dream.blog.csdn.net/article/details/90897493 |
略微休息一下,继续爬虫百例教程,本篇是66讲,偏后期的教程了
今天研究一下如何登录微博
登录操作是爬虫coder必须要掌握的基本技能之一
打开模拟登录,这个步骤可以使用不同的抓包工具,谷歌自带的开发者工具也可以实现
请注意,微博实现登录,入口和方式很多
最常见的
移动版 难度系数★★
https://passport.weibo.cn/signin/login?entry=mweibo
新浪其他版块做跳板 难度系数 ★★★
http://my.sina.com.cn/profile/unlogin/
微博首页右侧登录框 难度系数 ★★★★
找到登录入口,就需要开始抓取登录关键数据
关键数据分析
通过在网页填写用户名和密码,点击登录进行数据抓取
这个地方发现一个比较神奇的事情,用谷歌的开发者工具抓取,竟然空白,啥都没有
神奇了,不过我知道,这个地方一定是存在数据的
更换 青花瓷
软件
看图,果然有的
到这个地方,不用着急,开始着重分析login.php,我们必须要知道微博登录的所有参数
提取参数,能直接理解的参数,直接标注上含义
entry=weibo //入口,目测永久为weibo
gateway=1 //入口?1
from= // from 空
savestate=7 // 存储状态 7
qrcode_flag=false //二维码相关
useticket=1 // 用户凭证
pagerefer=https.......一个超链接 //某个页面
vsnf=1
su=bmV0ZHolNDBzaW5hLmNvbQ%3D%3D // su是什么???
service=miniblog // 忽略
servertime=1560214975 //服务器时间????
nonce=87F5BK // nonce 是什么?
pwencode=rsa2
rsakv=1330428213 // rsakv ??? rsa加密参数?
sp=一段加密的字符串 // sp加密的字符串
sr=1920*1080
encoding=UTF8
prelt=54
url=https......一个超链接
returntype=META
简单分析之后,你可以提取一些关键的参数出来,有些参数保持默认值即可
我们看一下,有哪些参数是最重要的
su
,servertime
,nonce
,sp
这四个参数最为重要
一一拆解参数
翻看一下刚才的链接,不难发现servertime
与nonce
两个参数已经被找到了
重点来了,sp和su是什么?
继续关注抓包数据
发现一个ssologin.js
这种js文件出现在这个位置,一定是用来加密的(爬虫写的多了,就知道了)
进入到内部,找数据来源
javascript格式化,自行进行即可
在这个链接中,我们找到一个回调函数 preloginCallBack
请注意,这个地方还有一个参数为su
查看su的值su: bmV0ZHolNDBzaW5hLmNvbQ==
简单猜测一下,比较容易,为Base64加密,Base64加密一般是一个=
结尾?这里咋出现了两个?
没事,一会删掉一个即可
继续翻ssologin.js
在里面找相关的方法
然后找到这部分源码
var makeRequest = function(username, password, savestate, qrcode_flag) {
var request = {
entry: me.getEntry(),
gateway: 1,
from: me.from,
savestate: savestate,
qrcode_flag: qrcode_flag,
useticket: me.useTicket ? 1 : 0
};
if (me.failRedirect) {
me.loginExtraQuery.frd = 1
}
request = objMerge(request, {
pagerefer: document.referrer || ""
});
request = objMerge(request, me.loginExtraFlag);
request = objMerge(request, me.loginExtraQuery);
request.su = sinaSSOEncoder.base64.encode(urlencode(username));
if (me.service) {
request.service = me.service
}
if ((me.loginType & rsa) && me.servertime && sinaSSOEncoder && sinaSSOEncoder.RSAKey) {
request.servertime = me.servertime;
request.nonce = me.nonce;
request.pwencode = "rsa2";
request.rsakv = me.rsakv;
var RSAKey = new sinaSSOEncoder.RSAKey();
RSAKey.setPublic(me.rsaPubkey, "10001");
password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password)
} else {
if ((me.loginType & wsse) && me.servertime && sinaSSOEncoder && sinaSSOEncoder.hex_sha1) {
request.servertime = me.servertime;
request.nonce = me.nonce;
request.pwencode = "wsse";
password = sinaSSOEncoder.hex_sha1("" + sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(password)) + me.servertime + me.nonce)
}
}
request.sp = password;
try {
request.sr = window.screen.width + "*" + window.screen.height
} catch(e) {}
return request
};
哇,发现所有的参数都找到了,厉害了
注意看request.sp = password
password是通过三次sha1
加密实现的
所有的参数目前为止,我们都找到了,下面要实现的就是写代码了
核心编码
获取servertime、nonce、rsakv等参数
from urllib.parse import quote
import requests,re,json,time,base64
def prelogin(username):
su = base64.b64encode(username.encode())
url = "https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su={}&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_={}".format(quote(su),int(time.time()*1000))
data = requests.request('GET', url).text
p = re.compile('\((.*)\)')
try:
json_data = p.search(data).group(1)
data = json.loads(json_data)
servertime = str(data['servertime'])
nonce = data['nonce']
rsakv = data['rsakv']
pubkey = data['pubkey']
return servertime, nonce,rsakv,pubkey
except:
print('没有获取到 severtime、nonce、rsakv 、pubkey')
return None
if __name__ == '__main__':
params = prelogin("你的微博登录邮箱")
print(params)
上述代码,可以成功的得到一些关键参数,拿到参数之后,就要进行下一步操作了
获取加密的sp
这个步骤是对JS加密过程的一个翻译
请注意,使用的RSA加密
代码模仿我框选的部分即可
安装rsa库
pip install rsa
from urllib.parse import quote
from binascii import b2a_hex
import requests,re,json,time,base64,rsa
def prelogin(username):
pass
def get_sp(pubkey,servertime,nonce,password):
'''用rsa对明文密码进行加密,加密规则翻译JS代码'''
# 生成公钥
# var RSAKey = new sinaSSOEncoder.RSAKey();
# RSAKey.setPublic(me.rsaPubkey, "10001");
# password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password)
publickey = rsa.PublicKey(int(pubkey, 16), int('10001', 16))
message = str(servertime) + '\t' + str(nonce) + '\n' + str(password)
sp = rsa.encrypt(message.encode(), publickey)
return b2a_hex(sp)
if __name__ == '__main__':
servertime, nonce, rsakv, pubkey = prelogin("你的邮箱")
sp = get_sp(pubkey, servertime, nonce, "你的密码")
一番努力之下,你已经成功获取到加密之后的sp参数
伪造请求
这部分代码比较简单了,就是凑齐请求参数,发起请求即可
重要的请注意,参数一定要写准
如果碰到还不清楚的参数,可以多尝试一下
比如返回类型这里,多次尝试后,发现使用
returntype = ‘TEXT’ 可以返回正确的JSON
而设置 META则需要获取content了(自己试试吧)
def login(username,password,servertime,nonce,rsakv,pubkey):
data = {
'entry': 'weibo',
'gateway': '1',
'from': 'null',
'savestate': '7',
'useticket': '1',
'vsnf': '1',
'su': get_su(username),
'service': 'account',
'servertime': servertime,
'nonce': nonce,
'pwencode': 'rsa2',
'rsakv': rsakv,
'sp': get_sp(pubkey,servertime,nonce,password),
'sr': '1920*1080',
'encoding': 'UTF-8',
'prelt': random.randint(1,100),
'url': 'https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
'returntype': 'TEXT'
}
print(data)
url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'
json_data = session.post(url,data=data).json()
print(json_data)
#判断post登录是否成功
if json_data['retcode'] == '0':
params = {
'ticket': json_data['ticket'],
'ssosavestate': int(time.time()),
'callback': 'sinaSSOController.doCrossDomainCallBack',
'scriptId': 'ssoscript0',
'client': 'ssologin.js(v1.4.19)',
'_': int(time.time()*1000)
}
#二次登录网页验证
url = 'https://passport.weibo.com/wbsso/login'
res = session.get(url,params=params)
print(res.text)
json_data1 = json.loads(re.search(r'({"result":.*})', res.text).group())
#判断是否登录成功
if json_data1['result'] is True:
print(res.cookies)
print(json_data1)
else:
print(json_data1)
else:
print(json_data)
最终得到重要信息,表示登录成功
如果设置META
url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'
json_data = session.post(url,data=data).content.decode("GBK")
print(json_data)
return
返回的数据,需要使用正则表达式进行匹配
代码完成,阅读起来有任何不明白的,可以私聊我
怎么找到我,自己想办法把
关注公主号,博客左侧有
回复微博,获取源码