這次嘗試模擬登錄微博批钠,獲取com網(wǎng)站cookie灯谣,cn不可用。
分析網(wǎng)站
- 首先打開weibo.com微博登錄頁面恨溜,如果已經(jīng)登錄需要先退出(其他的com登錄頁應(yīng)該也是可以的)。
- 打開chrome調(diào)試找前,查看傳輸狀態(tài)糟袁。清除記錄之后勾選 preserve log,再輸入帳號纸厉,當(dāng)輸入完帳號鼠標(biāo)點(diǎn)擊空白之后系吭,會觸發(fā)一個js事件五嫂,如上圖颗品。打開這個請求網(wǎng)址之后:發(fā)現(xiàn)這個json字典數(shù)據(jù)包含著下一步需要用的登錄表單,所以先注意一下沃缘,回頭再看躯枢。
-
輸入密碼之后登錄,觀察數(shù)據(jù)包槐臀。login.php看名字好像就是登錄的請求了锄蹂。 再看看它提交的數(shù)據(jù),sp就是密碼水慨,su就是帳號得糜。其他的數(shù)據(jù)怎么得到呢,我們就需要找到它執(zhí)行的ssologin.js了晰洒。
- 這個包也可以在js中找到朝抖,之后打開這個文件會看到一整片沒有格式化的js代碼,很頭疼谍珊≈涡可以
<c-f>
查找關(guān)鍵字rsa2
艳汽,這一塊就是加密代碼,很深奧有沒有歇父。這一塊搞了半天最后還是google出來的.-.-.
OK,到這已經(jīng)亂了盼忌。。绊茧。整理一下思路铝宵。
我們登錄的步驟是:輸入帳號 -> 網(wǎng)頁返回prelogin,這個里面包含表單信息 -> 網(wǎng)頁調(diào)用ssologin.js加密數(shù)據(jù) -> 提交數(shù)據(jù)华畏。
我們就需要:獲得prelogin數(shù)據(jù) -> 用python仿照ssologin.js把數(shù)據(jù)加密 -> 提交捉超。
上代碼
- 請求prelogin,獲取所需參數(shù)唯绍。用正則表達(dá)式截取字典拼岳,用eval函數(shù)把字符串轉(zhuǎn)換成字典類型,分別獲取值况芒。
prelogin_url = r'https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.15)' #noqa
def Prelogin(prelogin_url):
data = requests.get(prelogin_url).content.decode('utf-8')
p = re.compile('\((.*)\)')
data_str = p.search(data).group(1)
server_data_dict = eval(data_str)
pubkey = server_data_dict['pubkey']
servertime = server_data_dict['servertime']
nonce = server_data_dict['nonce']
rsakv = server_data_dict['rsakv']
return pubkey, servertime, nonce, rsakv
- 有了上面的數(shù)據(jù)就可以加密帳號密碼了惜纸,帳號是由url加密,再用base64加密绝骚。密碼就比較復(fù)雜了耐版,基本按照ssologin.js來。
def RSAEncoder(username, password, pubkey, servertime, nonce):
su_url = urllib.parse.quote_plus(username)
su_encoded = su_url.encode('utf-8')
su = base64.b64encode(su_encoded)
su = su.decode('utf-8')
rsaPublickey = int(pubkey, 16)
e = int('10001', 16)
key = rsa.PublicKey(rsaPublickey, e)
message = str(servertime) + '\t' + str(nonce) + '\n' + str(password)
password = rsa.encrypt(message.encode('utf-8'), key)
sp = binascii.b2a_hex(password)
return su, sp
- 數(shù)據(jù)準(zhǔn)備好了之后就能填表單了压汪。
def PostData(username, password, pubkey, servertime, nonce, rsakv):
su, sp = RSAEncoder(username, password, pubkey, servertime, nonce)
post_data = {
'encoding': 'UTF-8',
'entry': 'weibo',
'from': '',
'gateway': '1',
'nonce': nonce,
'pagerefer': '',
'prelt': '645',
'pwencode': 'rsa2',
'returntype': 'META',
'rsakv': rsakv,
'savestate': '7',
'servertime': str(servertime),
'service': 'miniblog',
'sp': sp,
'sr': '1920*1080',
'su': su,
'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack', #noqa
'useticket': '1',
'vsnf': '1',
}
return post_data
- 可以登錄了粪牲。第一次請求到的網(wǎng)頁不是登錄成功的頁面,而是一個重定向止剖,如圖腺阳,用正則表達(dá)式提取網(wǎng)址,進(jìn)行訪問穿香,成功亭引!
def login(self):
pubkey, servertime, nonce, rsakv = Prelogin(self.prelogin_url)
post_data = PostData(self.username, self.password, pubkey, servertime,
nonce, rsakv)
session = requests.Session()
response = session.post(self.login_url, params=post_data,
headers=self.headers)
text = response.content.decode('gbk')
pa = re.compile(r'location\.replace\(\'(.*?)\'\)')
redirect_url = pa.search(text).group(1)
response = session.get(redirect_url, headers=self.headers)
print(session.cookies)
GitHub開源地址:https://github.com/matianhe/crawler