您的位置:首页 > 其它

新浪微博登录

2016-04-16 11:35 375 查看
Reference: http://lovenight.github.io/2015/11/23/Python-%E6%A8%A1%E6%8B%9F%E7%99%BB%E5%BD%95%E6%96%B0%E6%B5%AA%E5%BE%AE%E5%8D%9A/
登录页: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
42

import 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

直接在浏览器中访问:
http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.18))

未登录状态返回:

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
10

def 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
2
3
4
5
6
7
8
9
1011
12
13
14
15
16
17

def getSu(username):
"""加密用户名,su为POST中的用户名字段"""
su = base64.b64encode(username.encode('utf-8')).decode('utf-8')
return su

def getSp(password, servertime, nonce, pubkey):
"""加密密码,sp为POST中的用户名字段"""
pubkey = int(pubkey, 16)
# 65537是js加密文件文件中的固定值,原是十六进制数字10001
key = rsa.PublicKey(pubkey, 65537)
# 以下拼接明文从js加密文件中得到
message = str(servertime) + '\t' + str(nonce) + '\n' + str(password)
message = message.encode('utf-8')
sp = rsa.encrypt(message, key)
# 把二进制数据的每个字节转换成相应的2位十六进制表示形式。
sp = binascii.b2a_hex(sp)
return sp

提交POST请求

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
42

def login(su, sp, servertime, nonce, rsakv):
postData = {
'entry': 'weibo',
'gateway': '1',
'from': '',
'savestate': '7',
'userticket': '1',
"pagerefer": "http://open.weibo.com/wiki/2/statuses/home_timeline",
"vsnf": "1",
"su": su,
"service": "miniblog",
"servertime": servertime,
"nonce": nonce,
"pwencode": "rsa2",
"rsakv": rsakv,
"sp": sp,
"sr": "1440*900",
"encoding": "UTF-8",
"prelt": "126",
"url": "http://open.weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack",
"returntype": "META",
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "login.sina.com.cn",
"Origin": "http://open.weibo.com",
"Referer": "http://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E",
"Upgrade-Insecure-Requests": "1",
}
loginURL = r'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)'
session = requests.Session()
session.headers = headers
res = session.post(loginURL, data=postData)
html = res.content.decode('gbk')
info = re.findall(r"location\.replace\(\'(.*?)\'", html)[0]
if 'retcode=0' in info:
print("登录成功!")
else:
print("登录失败!")
return session

完整代码

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
4243
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

import requests
import json
import re
import base64
import rsa
import binascii

def 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
def getSu(username):
"""加密用户名,su为POST中的用户名字段"""
su = base64.b64encode(username.encode('utf-8')).decode('utf-8')
return su

def getSp(password, servertime, nonce, pubkey):

"""加密密码,sp为POST中的用户名字段"""
pubkey = int(pubkey, 16)
key = rsa.PublicKey(pubkey, 65537)
# 以下拼接明文从js加密文件中得到
message = str(servertime) + '\t' + str(nonce) + '\n' + str(password)
message = message.encode('utf-8')
sp = rsa.encrypt(message, key)
# 把二进制数据的每个字节转换成相应的2位十六进制表示形式。
sp = binascii.b2a_hex(sp)
return sp

def login(su, sp, servertime, nonce, rsakv):
postData = {
'entry': 'weibo',
'gateway': '1',
'from': '',
'savestate': '7',
'userticket': '1',
"pagerefer": "http://open.weibo.com/wiki/2/statuses/home_timeline",
"vsnf": "1",
"su": su,
"service": "miniblog",
"servertime": servertime,
"nonce": nonce,
"pwencode": "rsa2",
"rsakv": rsakv,
"sp": sp,
"sr": "1440*900",
"encoding": "UTF-8",
"prelt": "126",
"url": "http://open.weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack",
"returntype": "META",
}
loginURL = r'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)'
session = requests.Session()
res = session.post(loginURL, data=postData)
html = res.content.decode('gbk')
info = re.findall(r"location\.replace\(\'(.*?)\'", html)[0]
if 'retcode=0' in info:
print("登录成功!")
else:
print("登录失败!")
return session

if __name__ == '__main__':
servertime, nonce, pubkey, rsakv = getLoginInfo()
su = getSu("你的用户名")
sp = getSp("你的密码", servertime, nonce, pubkey)
session = login(su, sp, servertime, nonce, rsakv)

#Python #新浪微博
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: