从零开始编写农场助手-4

分类: Python, Web 2.0, 笔记 | 标签: , | 日期:2010-04-14 | 332 views

上来先引用两篇文章,随着这两篇都是用C#来写的,一篇在这里,另一篇在。讲的都是如何得到腾讯加密的算法的。
本章我们需要解决从腾讯服务器那里获取cookie。所以,列了部分代码如下:

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
VCode=''
data={}
for item in inputDict:
    if 'name' not in item:
        #print item
        continue
    if item['name']=='fp':
        continue
    if item['name']=='u':
        print 'user:',item['value']
        print 'we set it to user'
        item['value']='user'
    if item['name']=='p':
        print 'password:',item['value']
        print 'we set it to correct password'
        item['value']=myjs.Run('md5',myjs.Run('md5_3','password')+VCode)
    data[item['name']]=item['value']
data['fp']='loginerroralert'
print data
 
import urllib
postheader={'Referer':'http://i.qq.com','Accept-Language':'zh-cn','Content-Type':'application/x-www-form-urlencoded',\
            'User-Agent':'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.1.4322; .NET CLR 2.0.50727)'}
opener=urllib2.build_opener()
postdata=urllib.urlencode(data)
request=urllib2.Request(action,postdata,postheader)
results=opener.open(request)
a=results.read()
print a

可惜,返回的是错误。

1
<html><head><meta http-equiv="Content-Language" content="zh-cn"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>登录失败</title>; </head><script language="Javascript">;alert("您的输入有误, 请重试。");history.go(-1);</script></html>

这是为啥子尼?再次嵌入到腾讯网页中,仔细寻找,发现有个函数干了一件事,来确定是否需要取得验证码

1
<input type="text" id="u" name="u" value="" style="ime-mode:disabled" tabindex="1" onfocus="ptui_onUserFocus('u', '#000000')" onblur="ptui_onUserBlue('u', '#CCCCCC');<span style="color: #ff0000;">check()</span>;" />

check()部分是重点。意思是,如果用户名输入区域失去焦点,则运行check函数。check函数如下:

1
2
3
4
5
6
7
8
function check(){
 var uin = ptui_trim(document.getElementById("u").value);
 if (g_uin == uin || (!ptui_checkQQUin(uin))){
  return;
 }
 g_uin = uin ;
 ptui_needVC(g_uin,g_appid);
}

 如果输入的用户名与以前的不同,则运行ptui_needVC(g_uin,g_appid);其中g_uin是新用户名,g_appid=15000101。再来看这个函数干了啥?

1
 function ptui_needVC(C,D){var B="http://ptlogin2."+g_domain+"/check?uin="+C+"&appid="+D+"&r="+Math.random();var A=document.createElement("script");A.src=B;document.body.appendChild(A);g_loadcheck=true;return }

原来引用了一个地址,并加入到了当前的文档中。以我的号码为例,测试了一下。返回的内容是:

1
ptui_checkVC('0','!V4D');

原来偷偷运行了一个函数。

1
function ptui_checkVC(A,B){g_loadcheck=false;if(g_submitting){return }if(A=="0"){document.getElementById("verifycode").value=B;loadVC(false)}else{document.getElementById("verifycode").value="";loadVC(true)}}

即如果A为0,则将verifycode偷偷改成B的内容,其实这时验证码是不可见的。而如果A不为0,则将验证码输入框内容重置,并调用loadVC函数来加载验证码。loadVC函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function loadVC(flag){
 if (isLoadVC == flag){
  return;
 }
 isLoadVC = flag;
 if (flag == true){
  var img = document.getElementById("imgVerify");
  img.src="http://ptlogin2.qq.com/getimage?aid=15000101&"+Math.random();
  document.getElementById("verifyinput").style.display="";
  document.getElementById("verifytip").style.display="";
  document.getElementById("verifyshow").style.display="";
  ptui_notifySize("login");
  try{
   document.getElementById("p").focus(); 
  }catch(e){}
 }else{
  document.getElementById("verifyinput").style.display="none";
  document.getElementById("verifytip").style.display="none";
  document.getElementById("verifyshow").style.display="none";
  ptui_notifySize("login");
 }
}

如果传入的flag为真,则直接返回。如果为假,则加载认证码。

于是,我们也通过这样的方法,获取验证码。然而向服务器提交请求之后,还是出错,不过返回的信息变了。

1
<html> <head><meta http-equiv="Content-Language" content="zh-cn"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>登录失败</title> </head><script language="Javascript">alert("系统繁忙,请稍后重试(50)。");history.go(-1);</script></html>

这说明离成功又进了一步。再回来看form代码

1
2
3
&lt;form id="loginform" autocomplete="off" name="loginform" action="http://ptlogin2.qq.com/login" method="post"
 
onsubmit="if(!isAbleSubmit){return false;};return <span style="color: #ff0000;">ptui_onLoginEx(loginform, 'qq.com')</span>" onreset="return onFormReset(loginform)" target="_self" style="margin:0px;"&gt;

注意红色函数,在点击form按钮的同时会验证数据的合法性,如果合法,则运行函数。查看该函数的代码

1
2
3
4
5
6
7
8
function ptui_onLoginEx(B,C){
    if(ptui_onLogin(B)){
        var A=new Date();
        A.setHours(A.getHours()+24*30);
        setCookie("ptui_loginuin",B.u.value,A,"/","ui.ptlogin2."+C)
    }
    return false
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 function ptui_onLogin(A){
     try{
          if(parent.ptlogin2_onLogin){
               if(!parent.ptlogin2_onLogin()){
                    return false
               }
          }
          if(parent.ptlogin2_onLoginEx){
               var D=A.u.value;
               var B=A.verifycode.value;
               if(ptui_str(STR_UINTIP)==D){D=""}
               if(!parent.ptlogin2_onLoginEx(D,B)){return false}
           }
     }catch(C){}
     return ptui_checkValidate(A)
}

看来要研究setCookie这个函数了。

1
2
3
4
5
6
7
8
9
function setCookie(C,E){
    var A=setCookie.arguments;
    var H=setCookie.arguments.length;
    var B=(2<H)?A[2]:null;
    var G=(3<H)?A[3]:null;
    var D=(4<H)?A[4]:null;
    var F=(5<H)?A[5]:null;
    document.cookie=C+"="+escape(E)+((B==null)?" ":(";expires ="+B.toGMTString()))+((G==null)?"  ":(";path = "+G))+((D==null)?" ":(";domain ="+D))+((F==true)?";secure":" ")
}

经过测试发现,C和E是传入的前两个参数,其他参数则通过A[索引]来取得。
所以,在提交表单过程中实际上是将用户名保存到了cookie中,并且设置过期时间为30天。

其实4月6号就写到这个位置了,一直没有发出来。现在开始忙论文,最近是没时间搞了。先见见光吧。

你也许会喜欢的日志

10人发表了评论  ↓发表评论↓
  • 哇塞,太牛掰啦

    [回复]

    lx 回复:

    @Pynn Yang, 你犯得着用我的主页地址吗。。。。搞得像虚假回复。。。给你改过来了

    [回复]

    Pynn Yang @ 2010年04月14日

    回复
  • 虽然没弄成功,,但是这一份很有帮助的文档,,,

    [回复]

    lx 回复:

    @fsdf, 最近有再做,但还是没有实质性进展。。。。

    [回复]

    fsdf @ 2010年06月7日

    回复
  • 没事干也在研究这个登录,也是在这里绊倒了,继续~ing

    [回复]

    lx 回复:

    可以交流交流

    [回复]

    Neeke 回复:

    @lx, O(∩_∩)O哈哈~已经解决了,登录成功了。

    [回复]

    lx 回复:

    恭喜啊

    Neeke @ 2010年06月24日

    回复
  • Knowledge wants to be free, just like these arltcies!

    [回复]

    lx 回复:

    @Yancy, your have some typos. arltcies should be articles

    [回复]

    Yancy @ 2011年07月17日

    回复

[ Ctrl+Enter提交 ]

3437471453591321281023251740504243322112038418334931126263041298715442436271424616193932548

Freelance PHP Developer