最近在学习使用SAE,打算往上面放一个微博抢沙发的脚本,需要登录状态才能使用微博API。解决方法有两个,一是浏览器登录,手动复制cookie,二是模拟登录。我选择后者。
网上搜到一份教程,《python使用rsa加密算法模块模拟新浪微博登录》,非常复杂。对照着做的过程中,自己又找出一个简单的登录方法。两种方法都登录成功,记录如下:
本文涉及的Python版本:3.4
自己找出来的简单方法
登录页:http://login.sina.com.cn/signup/signin.php?entry=sso
抓包可找到登录网址:
https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15/)&_=1448285708709
最后一项是时间戳,经测试,可以直接删除。所以最终登录网址是:
https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)
POST提交的表单中,用户名需要base64编码。
完整登录代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42import requests
import json
import base64
def login(username, password):
username = base64.b64encode(username.encode('utf-8')).decode('utf-8')
postData = {
"entry": "sso",
"gateway": "1",
"from": "null",
"savestate": "30",
"useticket": "0",
"pagerefer": "",
"vsnf": "1",
"su": username,
"service": "sso",
"sp": password,
"sr": "1440*900",
"encoding": "UTF-8",
"cdult": "3",
"domain": "sina.com.cn",
"prelt": "0",
"returntype": "TEXT",
}
loginURL = r'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)'
session = requests.Session()
res = session.post(loginURL, data = postData)
jsonStr = res.content.decode('gbk')
info = json.loads(jsonStr)
if info["retcode"] == "0":
print("登录成功")
# 把cookies添加到headers中,必须写这一步,否则后面调用API失败
cookies = session.cookies.get_dict()
cookies = [key + "=" + value for key, value in cookies.items()]
cookies = "; ".join(cookies)
session.headers["cookie"] = cookies
else:
print("登录失败,原因: %s" % info["reason"])
return session
if __name__ == '__main__':
session = login('你的用户名', '你的密码')
返回的session保存了登录状态,尽情做你做想做的事吧,配合微博API效果更佳。
网上搜索到的复杂方法
本节依赖的第三方库除了上面用过的requests
,还有用于加密的rsa
,需要另行安装。
登录流程
- 向如下网址提交GET请求,获取servertim、nonce、pubkey、rsakv,后两者是固定值。
http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.18)) - 加密用户名与密码
- 向如下网址提交POST请求:
http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18))
加密方式的破解找到一段方法,我没学过javascript,就没细看,直接照搬后面的加密方法。
获得以及查看新浪微博登录js文件:
查看新浪通行证url(http://login.sina.com.cn/signup/signin.php)的源代码,其中可以找到该js的地址http://login.sina.com.cn/js/sso/ssologin.js,不过打开后里面的内容是加密过的,可以在网上找个在线解密站点解密,查看最终用户名和密码的加密方式。
分步实现
获取servertim和nonce
未登录状态返回:
sinaSSOController.preloginCallBack({
"retcode": 0,
"servertime": 1448278360,
"pcid": "gz-8139fa256b150b7a42e09dbdc0b4ed2224eb",
"nonce": "RDY5SN",
"pubkey": "EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443",
"rsakv": "1330428213",
"exectime": 9
})
取出括号里的JSON字符串提取信息:1
2
3
4
5
6
7
8
9
10def getLoginInfo():
preLoginURL = r'http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.18)'
html = requests.get(preLoginURL).text
jsonStr = re.findall(r'\((\{.*?\})\)', html)[0]
data = json.loads(jsonStr)
servertime = data["servertime"]
nonce = data["nonce"]
pubkey = data["pubkey"]
rsakv = data["rsakv"]
return servertime, nonce, pubkey, rsakv
加密用户名与密码
1 | def getSu(username): |
提交POST请求
1 | def login(su, sp, servertime, nonce, rsakv): |
完整代码
1 | import requests |