python關於模擬登錄微博(PC)

微博模擬登錄javascript

1.基類對象的方法
創建一個類
__init__初始化方法,接收username和password。php

class launcher():
def __init__(self, username, password):
self.password = password
self.username = usernamehtml

2.定義一個函數,目的用於取到nonce , servertime , pubkey信息
僞造一個request用於獲取預登錄信息
def get_prelogin_args(self):java

json_pattern = re.compile('\((.*)\)') 這個是我輸入帳號可是沒登陸獲得的一個json文件
url = 'https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&' + self.get_encrypted_name() + '&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)'
try:
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
raw_data = response.read().decode('utf-8')
json_data = json_pattern.search(raw_data).group(1)
data = json.loads(json_data)
return data
except urllib.error as e:
print("%d" % e.code)
return Nonepython

3.定義一個方法,解密rsa加密的密碼,其中必須的pubkey , nonce , rsakv等關鍵字使用一個字典data 傳入
def get_encrypted_pw(self, data):
rsa_e = 65537 # 0x10001(轉換成10進制)
pw_string = str(data['servertime']) + '\t' + str(data['nonce']) + '\n' + str(self.password)
key = rsa.PublicKey(int(data['pubkey'], 16), rsa_e)
pw_encypted = rsa.encrypt(pw_string.encode('utf-8'), key)
self.password = '' # 清空password
passwd = binascii.b2a_hex(pw_encypted) #換成16進制
print(pw_encypted)
print(passwd)
return passwdajax

4.定義一個方法,解密base64加密的帳號(手機帳號會被混淆,%3D是=號,郵箱帳號@會變成%40)
def get_encrypted_name(self):
username_urllike = urllib.request.quote(self.username)
username_encrypted = base64.b64encode(bytes(username_urllike, encoding='utf-8'))
return username_encrypted.decode('utf-8')json

5.創建一個cookie容器用於整個登陸過程的cookie的綁定
def enableCookies(self):
# 創建一個cookies 容器
cookie_container = http.cookiejar.CookieJar()
# 將一個cookies容器和一個HTTP的cookie的處理器綁定
cookie_support = urllib.request.HTTPCookieProcessor(cookie_container)
# 建立一個opener,設置一個handler用於處理http的url打開
opener = urllib.request.build_opener(cookie_support, urllib.request.HTTPHandler)
# 安裝opener,此後調用urlopen()時會使用安裝過的opener對象
urllib.request.install_opener(opener)服務器

6.POST表單提交
def build_post_data(self, raw):
post_data = {
"entry": "weibo",
"gateway": "1",
"from": "",
"savestate": "7",
"useticket": "1",
"pagerefer": "https://www.baidu.com/link?url=2m74RGf8hzJIXFwGexWMuQWqqmvcpu-nMjK8cyuZIcC&wd=&eqid=85fee59800006e0c000000025a4cbc7b",
"vsnf": "1",
"su": self.get_encrypted_name(),
"service": "miniblog",
"servertime": raw['servertime'],
"nonce": raw['nonce'],
"pwencode": "rsa2",
"rsakv": raw['rsakv'],
"sp": self.get_encrypted_pw(raw),
"sr": "1366*768",
"encoding": "UTF-8",
"prelt": "854",
"url": "https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack",
"returntype": "MENT"
}
data = urllib.parse.urlencode(post_data).encode('utf-8')
return datacookie

7.開始登陸
def login(self):
url = 'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'
self.enableCookies()mvc

data = self.get_prelogin_args()
post_data = self.build_post_data(data)
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
}
try:
request = urllib.request.Request(url=url, data=post_data, headers=headers)
response = urllib.request.urlopen(request)
html = response.read().decode('GBK')
print(html)
except urllib.error as e:
print('-------------------------')
print(e.code)
打印出
html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>新浪通行證</title>


<script charset="utf-8" src="https://i.sso.sina.com.cn/js/ssologin.js"></script>
</head>
<body>
正在登陸 ...
<script>
try{sinaSSOController.setCrossDomainUrlList({"retcode":0,"arrURL":["https:\/\/passport.97973.com\/sso\/crossdomain?action=login&savestate=1546602068","https:\/\/passport.krcom.cn\/sso\/crossdomain?service=krvideo&savestate=1&ticket=ST-NTgxNjY5MjI5NQ%3D%3D-1515066068-tc-85B8AE28E184F1A1E0435DA6D4DFBBA3-1&ssosavestate=1546602068","https:\/\/passport.weibo.cn\/sso\/crossdomain?action=login&savestate=1"]});}
catch(e){
var msg = e.message;
var img = new Image();
var type = 1;
img.src = 'https://login.sina.com.cn/sso/debuglog?msg=' + msg +'&type=' + type;
}try{sinaSSOController.crossDomainAction('login',function(){location.replace('https://passport.weibo.com/wbsso/login?ssosavestate=1546602068&url=https%3A%2F%2Fweibo.com%2Fajaxlogin.php%3Fframelogin%3D1%26callback%3Dparent.sinaSSOController.feedBackUrlCallBack&display=0&ticket=ST-NTgxNjY5MjI5NQ==-1515066068-tc-240ED98A102AB2CF543CA399EF087D0C-1&retcode=0');});}
catch(e){
var msg = e.message;
var img = new Image();
var type = 2;
img.src = 'https://login.sina.com.cn/sso/debuglog?msg=' + msg +'&type=' + type;
}
</script>
</body>
</html>

8.第一次重定向

p = re.compile('location\.replace\([\'"](.*?)[\'"]\)')
try:
login_url = p.search(html).group(1)
print(login_url)
request = urllib.request.Request(login_url)
response = urllib.request.urlopen(request)
page = response.read().decode('GBK')
print(page)
打印出
<html><head><script language='javascript'>parent.sinaSSOController.feedBackUrlCallBack({"result":true,"userinfo":{"uniqueid":"5816692295","userid":null,"displayname":null,"userdomain":"?wvr=5&lf=reg"}});</script></head><body></body></html>

9.第二次重定向
p2 = re.compile(r'"userdomain":"(.*?)"')
try:
login_url = 'http://weibo.com/' + p2.search(page).group(1)
print(login_url)
request = urllib.request.Request(login_url)
response = urllib.request.urlopen(request)
final = response.read().decode('utf-8')
print(final)

 完整代碼

import urllib.error
import urllib.request
import re
import rsa
import http.cookiejar  # 從前的cookielib
import base64
import json
import urllib
import urllib.parse
import binascii


# 用於模擬登錄新浪微博

class launcher():
    def __init__(self, username, password):
        self.password = password
        self.username = username

    def get_prelogin_args(self):

        '''
        該函數用於模擬預登陸過程,並獲取服務器返回的 nonce , servertime , pub_key 等信息
        '''
        json_pattern = re.compile('\((.*)\)')
        url = 'https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&' + self.get_encrypted_name() + '&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)'
        try:
            request = urllib.request.Request(url)
            response = urllib.request.urlopen(request)
            raw_data = response.read().decode('utf-8')
            json_data = json_pattern.search(raw_data).group(1)
            data = json.loads(json_data)
            return data
        except urllib.error as e:
            print("%d" % e.code)
            return None

    def get_encrypted_pw(self, data):
        rsa_e = 65537  # 0x10001
        pw_string = str(data['servertime']) + '\t' + str(data['nonce']) + '\n' + str(self.password)
        key = rsa.PublicKey(int(data['pubkey'], 16), rsa_e)
        pw_encypted = rsa.encrypt(pw_string.encode('utf-8'), key)
        self.password = ''  # 清空password
        passwd = binascii.b2a_hex(pw_encypted)
        print(pw_encypted)
        print(passwd)
        return passwd

    def get_encrypted_name(self):
        username_urllike = urllib.request.quote(self.username)
        username_encrypted = base64.b64encode(bytes(username_urllike, encoding='utf-8'))
        return username_encrypted.decode('utf-8')

    def enableCookies(self):
        # 創建一個cookies 容器
        cookie_container = http.cookiejar.CookieJar()
        # 將一個cookies容器和一個HTTP的cookie的處理器綁定
        cookie_support = urllib.request.HTTPCookieProcessor(cookie_container)
        # 建立一個opener,設置一個handler用於處理http的url打開
        opener = urllib.request.build_opener(cookie_support, urllib.request.HTTPHandler)
        # 安裝opener,此後調用urlopen()時會使用安裝過的opener對象
        urllib.request.install_opener(opener)

    def build_post_data(self, raw):
        post_data = {
            "entry": "weibo",
            "gateway": "1",
            "from": "",
            "savestate": "7",
            "useticket": "1",
            "pagerefer": "https://www.baidu.com/link?url=2m74RGf8hzJIXFwGexWMuQWqqmvcpu-nMjK8cyuZIcC&wd=&eqid=85fee59800006e0c",
            "vsnf": "1",
            "su": self.get_encrypted_name(),
            "service": "miniblog",
            "servertime": raw['servertime'],
            "nonce": raw['nonce'],
            "pwencode": "rsa2",
            "rsakv": raw['rsakv'],
            "sp": self.get_encrypted_pw(raw),
            "sr": "1366*768",
            "encoding": "UTF-8",
            "prelt": "854",
            "url": "https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack",
            "returntype": "MENT"
        }
        data = urllib.parse.urlencode(post_data).encode('utf-8')
        return data

    def login(self):
        url = 'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'
        self.enableCookies()

        data = self.get_prelogin_args()
        post_data = self.build_post_data(data)
        headers = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
        }
        try:
            request = urllib.request.Request(url=url, data=post_data, headers=headers)
            response = urllib.request.urlopen(request)
            html = response.read().decode('GBK')
            print(html)
        except urllib.error as e:
            print('-------------------------')
            print(e.code)

        p = re.compile('location\.replace\([\'"](.*?)[\'"]\)')
        p2 = re.compile(r'"userdomain":"(.*?)"')

        try:
            login_url = p.search(html).group(1)
            print(login_url)
            request = urllib.request.Request(login_url)
            response = urllib.request.urlopen(request)
            page = response.read().decode('GBK')
            print(page)
            login_url = 'http://weibo.com/' + p2.search(page).group(1)
            print(login_url)
            request = urllib.request.Request(login_url)
            response = urllib.request.urlopen(request)
            final = response.read().decode('utf-8')
            print(final)
        except Exception as err:
            print(err)
            # return 0


if __name__ == '__main__':
    launcher = launcher('', '')  # 郵箱(帳號)、密碼
    if launcher.login() == True:
        print("登錄成功!")
相關文章
相關標籤/搜索