腾讯微博 自动登录脚本(python)

国内几大主要门户微博都公布了api,ms腾讯没有,中国互联网企业中腾讯始终是个奇葩。清明节闲来无事,弄个腾讯微博的自动登录脚本,也算作是对腾讯微博登录以及加密方式的研究。本人所作的研究仅供学习交流之用,如别有用心与本人无关。

1.python中 bytes 与 string 之间的转换

b = b"example" s = "example"
# str to bytes
bytes(s, encoding = "utf8")
# bytes to str
str(b, encoding = "utf-8")
# an alternative method
# str to bytes
str.encode(s)
# bytes to str
bytes.decode(b)

注意支持这个转换的python版本ms要3.0以上的吧,这一部分参考网页:http://blog.fuqcool.com/tag/python%20str%20string%20bytes%20%E8%BD%AC%E6%8D%A2

2,腾讯密码校验码混合加密策略python实现

     腾讯QQ的网页登陆 微博的登陆账号和密码都是一致的,均为qq账号和密码,在网站提交的过程中通过comm.js进行加密提交数据。腾讯数据提交是用get方式提交的,用httpfox插件查看的时候你会发现没有post方法,蛋疼吧。呵呵,腾讯为了防止用户的攻击,采取了三轮md5加密和第四轮混合验证码md5加密。md5算法本身是单向的,但是利用字典可以做到一部分的破解,因此腾讯对账号和密码采取多轮加密方式,这就是互联网的技术品质保证。

    有两种思路实现密码验证码最终的混合结果:一种是利用js引擎在本地执行js得到最终的结果,这就是典型的拿来主义,站在了巨人的肩膀上。另外一种是采用别的语言重写js脚本,这种方法可以学习md5加密并对腾讯的这个加密过程有很清晰的认识,我采取了第二种方式。关于加密的具体过程可以参见腾讯给我们提供的js脚本:login_div.js:

import hashlib
#腾讯的密码加密策略按照fxx筒靴的话说是个极品,通过查看login.js发现fxx筒靴此话不假啊
def Md5_3(password):
     #三次密码值的md5迭代
     m1 =hashlib.md5()
     m1.update(password)
     m2 =hashlib.md5()
     m2.update(m1.digest())
     m3 = hashlib.md5()
     m3.update(m2.digest())
     return m3.hexdigest()

def Md5_Final(password, verifycode):
    #三次密码值的MD5迭代与验证码值的混合hash
     m =hashlib.md5()
     strMixedTarget = Md5_3(password).upper()+str(verifycode, 'utf-8').upper()
     byteMixedTarget = bytes(strMixedTarget, 'utf-8')
     m.update(byteMixedTarget)
     return  m.hexdigest().upper()
if '__name__= __main__':
     pwd=b"ChenxofHit"
     verifycode = b"efta"
     print(Md5_Final(pwd, verifycode))
执行结果:

Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on Chenx, Standard
>>> 8E20D9A4C14208D18DD5CA9661AE798D

3.验证码的获取

 在上文之中提到了混合加密策略,在上文的代码中verifycode = b"efta" 是直接给出的,实际上验证码是通过类似链接http://ptlogin2.qq.com/check?uin=723357969&appid=4600010&r=0.024315022575277512得到的

下面的代码就是获取VC:

import random,re
import urllib.request

def getVC(uin,appid ="4600010"):
    r = random.random()
    url = "http://ptlogin2.qq.com/check?"+"uin="+uin+"&"+"appid="+appid+"&"+"r="+str(r)
    print(url)
    vc = None
    try:
        avatar = urllib.request.urlopen(url)
    except :
        print("Cannot connect to the remote host!")
        return vc
    else:
        vcTarget =avatar.read().decode("utf8")
        print(vcTarget)
        m = re.search(r'!.{3}', vcTarget)
        if m is not None:
            vc = m.group()
        else:
            print("VC Not getted!")
    return vc

def encode_b_VC(vc):
    vc = bytes(vc, 'utf-8')
    return vc
    
if __name__ == '__main__':
    uin="723357969"
    vc = getVC(uin)
    print(vc)

4.Cookie的设置:

利用firefox的HttpFox插件,可以客户端向服务器发送的消息。关于Header中Cookie设置的具体过程可以参见腾讯给我们提供的js脚本:ping.js:

from datetime import datetime
import random
def set_pgv_pvid():
    curMs  =datetime.utcnow().second
    pvidtmp = (round(random.random() * 2147483647) * curMs) % 10000000000
    return pvidtmp

def  set_pgv_flv():  #flash version
    pgv_flv = "10.2 r152"
    return pgv_flv


def set_pgv_info():
    curMs  =datetime.utcnow().second
    ssid = "s" + str( (round(random.random() * 2147483647) * curMs) % 10000000000 )
    return ssid

def set_pgv_r_cookie():
    datenow = datetime.now()
    dateUTCnow  = datetime.utcnow()
    pgv_r_cookie  = datenow.year % 100 + (dateUTCnow.month + 1) + dateUTCnow.day + dateUTCnow.microsecond  + round(random.random() * 100000)
    return pgv_r_cookie


def setCookies():
    pgv_pvid = set_pgv_pvid()
    pgv_flv = set_pgv_flv()
    pgv_info = set_pgv_info()
    pgv_r_cookie = set_pgv_r_cookie()
    #  pgv_pvid=6069385845; pgv_flv=10.1 r102; pgv_info=ssid=s3027620338; pgv_r_cookie=114719260880
    cookie = "pgv_pvid="+str(pgv_pvid)+";"+"pgv_flv="+str(pgv_flv)+";"+"pgv_info=ssid="+str(pgv_info)+";"+"pgv_r_cookie="+str(pgv_r_cookie)
    #print(cookie)
    return cookie


if '__name__= __main__':
    print(setCookies())

5.综合测试:

import QQMB_pwdEncryption as QPwd
import QQMB_setCookies as QCookie
import  QQMB_verifyCode   as QVC

import http.cookiejar, urllib.request, urllib.parse

loginUrl = "http://ptlogin2.qq.com/login?"

if '__name__ = __main__':
    uin = "723357969"
    pwd =b"*******"
    vc = QVC.getVC(uin)
    if vc is not None:
        encPwd = QPwd.Md5_Final(pwd, QVC.encode_b_VC(vc)) #After four cycle encryption
        print(encPwd)
        #http://ptlogin2.qq.com/login?u=723357969&p=8B8F042EE71CD0C55476201A2F1E18F7&verifycode=!08L&low_login_enable=1&low_login_hour=720&aid=46000101&u1=http%3A%2F%2Ft.qq.com&ptredirect=1&h=1&from_ui=1&dumy=&fp=loginerroralert

        cj = http.cookiejar.CookieJar()
        opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
        urllib.request.install_opener(opener)
        req =urllib.request.Request(loginUrl)
        #req.add_header("Host","ptlogin2.qq.com")
        req.add_header("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15")
        req.add_header("Accept-Charset","GB2312,utf-8;q=0.7,*;q=0.7")
        req.add_header("Referer","http://t.qq.com/")
        req.add_header("Cookie", QCookie.setCookies())

        parameters = { 'u':uin,
                              'p':encPwd,
                              'verifycode':vc,
                              'low_login_enable':'1',
                              'low_login_hour':'720',
                              'aid':'46000101',
                              'u1':'http%3A%2F%2Ft.qq.com',
                              'ptredirect':'1',
                              'from_ui':'1',
                              'dumy':'',
                              'fp':'loginerroralert'
                            }
        paraEncode = urllib.parse.urlencode(parameters).encode("GB2312")
        print(paraEncode)
        res = urllib.request.urlopen(req, paraEncode)
        html=res.read().decode('utf-8')
        print(html)

    else:
        print("VC Not getted Properly!Try it again!")

    在这里重申一遍,以上研究纯属个人学习交流之用,如果用于其它用途引起不必要的纠纷本人概不负责。

参考网页:

http://hi.baidu.com/qiuzhiying2200/blog/item/b9e5c4cb33873653f21fe71d.html 深圳研究生院的学长的日志 顶

http://www.cnblogs.com/bboy/archive/2010/10/29/1864537.html   Python网页抓取、模拟登录(以登录博客园为例)

http://www.city792.com/QQbiaoqing/2010/0921/1163.html 腾讯qq空间网页登陆真的很变态:小说,腾讯的登陆POST

(Python2.X到python3.x之间的变化很大,这个没有办法,多看api吧)

posted on 2011-04-03 23:11  追求卓越 挑战极限  阅读(4098)  评论(10编辑  收藏  举报

导航