Python模拟登陆 —— 征服验证码 9 微博weibo.com

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 登录界面抓包分析可以使用Http Analyzer,Filders,但是看起来很复杂,还是使用火狐好(chrome远远没有火狐好用)。首先,在输入用户名后,会进行预登录,网址为:http://login.
img_cf5e0c59445e2ec1b8cbe5c11e035912.png
登录界面

抓包分析可以使用Http Analyzer,Filders,但是看起来很复杂,还是使用火狐好(chrome远远没有火狐好用)。

首先,在输入用户名后,会进行预登录,网址为:http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=ZW5nbGFuZHNldSU0MDE2My5jb20%3D&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.18)&_=1443156845536,通过响应(sinaSSOController.preloginCallBack({"retcode":0,"servertime":1443156842,"pcid":"gz-e88b75a929252baec7c12c741985eaa45627","nonce":"2L4IZ3","pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213","showpin":0,"exectime":16})),我们可以获得四个有用的变量,servertime、nonce、pubkey和rsakv。

新浪微博的用户名加密目前采用Base64加密算法,而新浪微博登录密码的加密算法使用RSA2,这是模拟登陆的重点,需要先创建一个rsa公钥,公钥的两个参数新浪微博都给了固定值,第一个参数是登录第一步中的pubkey,第二个参数是js加密文件中的‘10001’(针对网友的提问进行更新:这个其实就是在ssologin.js的响应中). 这两个值需要先从16进制转换成10进制,把10001转成十进制为65537,随后加入servertime和nonce再次加密。

要提交的数据是:

postdata = {
        'entry': 'weibo',
        'gateway': '1',
        'from': '',
        'savestate': '7',
        'useticket': '1',
        'pagerefer': "http://login.sina.com.cn/sso/logout.php?entry=miniblog&r=http%3A%2F%2Fweibo.com%2Flogout.php%3Fbackurl",
        'vsnf': '1',
        'su': su,
        'service': 'miniblog',
        'servertime': servertime,
        'nonce': nonce,
        'pwencode': 'rsa2',
        'rsakv': rsakv,
        'sp': password_secret,
        'sr': '1366*768',
        'encoding': 'UTF-8',
        'prelt': '115',
        'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
        'returntype': 'META'
        }

提交之后,因为重定向,还要获取重定向的url。

使用python3。

import time
import base64
import rsa
import binascii
import requests
import re
import random
try:
    from PIL import Image
except:
    pass
try:
    from urllib.parse import quote_plus
except:
    from urllib import quote_plus

'''
如果没有开启登录保护,不用输入验证码就可以登录
如果开启登录保护,需要输入验证码

'''


# 构造 Request headers
agent = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0'
headers = {
    'User-Agent': agent
}

session = requests.session()

# 访问 初始页面带上 cookie
index_url = "http://weibo.com/login.php"
try:
    session.get(index_url, headers=headers, timeout=2)
except:
    session.get(index_url, headers=headers)
try:
    input = raw_input
except:
    pass


def get_su(username):
    """
    对 email 地址和手机号码 先 javascript 中 encodeURIComponent
    对应 Python 3 中的是 urllib.parse.quote_plus
    然后在 base64 加密后decode
    """
    username_quote = quote_plus(username)
    username_base64 = base64.b64encode(username_quote.encode("utf-8"))
    return username_base64.decode("utf-8")


# 预登陆获得 servertime, nonce, pubkey, rsakv
def get_server_data(su):
    pre_url = "http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su="
    pre_url = pre_url + su + "&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.18)&_="
    pre_url = pre_url + str(int(time.time() * 1000))
    pre_data_res = session.get(pre_url, headers=headers)

    sever_data = eval(pre_data_res.content.decode("utf-8").replace("sinaSSOController.preloginCallBack", ''))

    return sever_data


# print(sever_data)


def get_password(password, servertime, nonce, pubkey):
    rsaPublickey = int(pubkey, 16)
    key = rsa.PublicKey(rsaPublickey, 65537)  # 创建公钥
    message = str(servertime) + '\t' + str(nonce) + '\n' + str(password)  # 拼接明文js加密文件中得到
    message = message.encode("utf-8")
    passwd = rsa.encrypt(message, key)  # 加密
    passwd = binascii.b2a_hex(passwd)  # 将加密信息转换为16进制。
    return passwd


def get_cha(pcid):
    cha_url = "http://login.sina.com.cn/cgi/pin.php?r="
    cha_url = cha_url + str(int(random.random() * 100000000)) + "&s=0&p="
    cha_url = cha_url + pcid
    cha_page = session.get(cha_url, headers=headers)
    with open("cha.jpg", 'wb') as f:
        f.write(cha_page.content)
        f.close()
    try:
        im = Image.open("cha.jpg")
        im.show()
        im.close()
    except:
        print(u"请到当前目录下,找到验证码后输入")


def login(username, password):
    # su 是加密后的用户名
    su = get_su(username)
    sever_data = get_server_data(su)
    servertime = sever_data["servertime"]
    nonce = sever_data['nonce']
    rsakv = sever_data["rsakv"]
    pubkey = sever_data["pubkey"]
    showpin = sever_data["showpin"]
    password_secret = get_password(password, servertime, nonce, pubkey)

    postdata = {
        'entry': 'weibo',
        'gateway': '1',
        'from': '',
        'savestate': '7',
        'useticket': '1',
        'pagerefer': "http://login.sina.com.cn/sso/logout.php?entry=miniblog&r=http%3A%2F%2Fweibo.com%2Flogout.php%3Fbackurl",
        'vsnf': '1',
        'su': su,
        'service': 'miniblog',
        'servertime': servertime,
        'nonce': nonce,
        'pwencode': 'rsa2',
        'rsakv': rsakv,
        'sp': password_secret,
        'sr': '1366*768',
        'encoding': 'UTF-8',
        'prelt': '115',
        'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
        'returntype': 'META'
        }
    login_url = 'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)'
    if showpin == 0:
        login_page = session.post(login_url, data=postdata, headers=headers)
    else:
        pcid = sever_data["pcid"]
        get_cha(pcid)
        postdata['door'] = input(u"请输入验证码")
        login_page = session.post(login_url, data=postdata, headers=headers)
    login_loop = (login_page.content.decode("GBK"))
    # print(login_loop)
    pa = r'location\.replace\([\'"](.*?)[\'"]\)'
    loop_url = re.findall(pa, login_loop)[0]
    # print(loop_url)
    # 此出还可以加上一个是否登录成功的判断,下次改进的时候写上
    login_index = session.get(loop_url, headers=headers)
    uuid = login_index.text
    uuid_pa = r'"uniqueid":"(.*?)"'
    uuid_res = re.findall(uuid_pa, uuid, re.S)[0]
    web_weibo_url = "http://weibo.com/%s/profile?topnav=1&wvr=6&is_all=1" % uuid_res
    weibo_page = session.get(web_weibo_url, headers=headers)
    weibo_pa = r'<title>(.*?)</title>'
    # print(weibo_page.content.decode("utf-8"))
    userID = re.findall(weibo_pa, weibo_page.content.decode("utf-8", 'ignore'), re.S)[0]
    print(u"欢迎你 %s, 登陆成功" % userID)


if __name__ == "__main__":
    username = input(u'用户名:')
    password = input(u'密码:')
    login(username, password)

另可参考:
http://blog.csdn.net/andrewseu/article/details/48730735
http://www.jianshu.com/p/816594c83c74
https://github.com/ResolveWang

目录
相关文章
|
2月前
|
数据采集 自然语言处理 API
Python反爬案例——验证码的识别
Python反爬案例——验证码的识别
45 2
|
2月前
|
数据采集 自然语言处理 Python
用 Python 生成并识别图片验证码
用 Python 生成并识别图片验证码
45 1
|
2月前
|
数据采集 消息中间件 API
Python爬虫验证码识别——手机验证码的自动化处理
Python爬虫验证码识别——手机验证码的自动化处理
107 0
|
2月前
|
文字识别 开发者 iOS开发
Python反爬机制-验证码(一)
Python反爬机制-验证码(一)
29 0
|
2月前
|
人工智能 文字识别 API
Python反爬机制-验证码(二)
Python反爬机制-验证码(二)
19 0
|
4月前
|
数据采集 存储 自然语言处理
基于Python的微博热点李佳琦忒网友话题的评论采集和情感分析的方法,利用情感分析技术对评论进行情感倾向性判断
本文介绍了一种基于Python的方法,用于采集微博热点话题下的评论数据,并运用情感分析技术对这些评论进行情感倾向性判断,进而通过统计分析和可视化技术展示网友对特定话题的情感态度,对品牌或个人形象管理、用户需求发现、舆情监测和危机管理等方面具有重要价值。
基于Python的微博热点李佳琦忒网友话题的评论采集和情感分析的方法,利用情感分析技术对评论进行情感倾向性判断
|
4月前
|
机器学习/深度学习 数据采集 算法
【python】python基于微博互动数据的用户类型预测(随机森林与支持向量机的比较分析)(源码+数据集+课程论文)【独一无二】
【python】python基于微博互动数据的用户类型预测(随机森林与支持向量机的比较分析)(源码+数据集+课程论文)【独一无二】
|
5月前
|
并行计算 Java 大数据
深度探索:Python异步编程如何优雅征服IO密集型任务,让CPU密集型任务也臣服!
【7月更文挑战第17天】Python的异步编程借助`asyncio`库提升IO密集型任务效率,如并发下载网页,通过`async def`定义协程,`asyncio.gather`并发执行。在CPU密集型任务中,结合`ThreadPoolExecutor`实现并行计算,利用多核优势。`asyncio.run`简化事件循环管理,使Python在高负载场景下表现更佳。
67 4
|
5月前
|
自然语言处理 算法 安全
Python实现贝叶斯算法疫情微博评论情感分析
Python实现贝叶斯算法疫情微博评论情感分析
Python实现贝叶斯算法疫情微博评论情感分析
|
5月前
|
数据可视化 数据挖掘 数据处理
数据之美,尽收眼底!Python数据分析师如何利用Matplotlib、Seaborn打造视觉盛宴,征服数据世界?
【7月更文挑战第22天】Python的Matplotlib和Seaborn库是数据可视化的利器。Matplotlib基础强大,灵活定制,适合各类图表;Seaborn在其上层封装,提供美观的统计图形,简化复杂操作。结合使用,它们助数据分析师揭示数据规律,打造视觉盛宴,征服数据世界。示例代码分别展示了如何绘制正弦波图和箱线图。
40 0