用python登录Dr.com思路以及代码分享
前提:isp得支持web登录的方式。
说明:每个ISP的登录页面不一样,不过我估计算法都是一样的,于是解决方案应该也是相似的,只是表单的key可能不太一样。
首先,分析登录页面。
页面head镶嵌了<script>标签,所有的提交相关的脚本都在这里。页面关键部分是两个表单:f1和f0。整个f0是看不见的,但是点击f1的提交时,会直接调用f0的提交而不是提交自己。表单的table布局就不吐槽了...
部分HTML
<formname="f1"method="post"action=""onsubmit="returnee()"> <tableborder="0"width="100%"cellspacing="1"cellpadding="0"height="100%"class="f1"> ... <tr> <tdheight="34"width="35%"align="right">账号Account</td><tdheight="34"width="64%"><inputname="DDDDD"type="text"maxlength="26"class="input-border"></td> </tr> <tr> <tdheight="32"width="35%"align="right">密码Password</td><tdheight="32"width="64%"><inputname="upass"type="password"maxlength="16"class="input-border"></td> </tr> <tr> <tdheight="57"width="35%"></td><tdheight="57"width="64%"><inputtype="submit"name="0MKKey"value=""onclick="cc(0)"class="login-b"><inputtype="submit"name=""value=""onclick="reset();returnfalse;"></td> </tr> ... </form>
这里可以看见,点击submit的时候,调用cc(0),提交的时候调用ee()函数
部分js:
functioncc(ss){ f0.R1.value=ss; } functionee(){ if(f1.DDDDD.value==""){ alert("请输入您的账号Pleaseenteryouraccountaccountnumber"); returnfalse; } f0.DDDDD.value=f1.DDDDD.value if(ps==0){ f0.upass.value=xproc1(f1.upass.value); }else{ tmpchar=pid+f1.upass.value+calg; f0.upass.value=calcMD5(tmpchar)+calg+pid; f0.R2.value=1; } document.f0.submit(); returnfalse; }
显然,点击提交后,会对f0进行一系列赋值,如果没有问题就会提交f0
f0:
<formname="f0"method="post"action=""><inputtype="hidden"name="DDDDD"value="0"><inputtype="hidden"name="upass"value="0"> <inputtype="hidden"name="R1"value="0"><inputtype="hidden"name="R2"value="0"><inputtype="hidden"name="para"value="00"> <inputtype="hidden"name="0MKKey"value="123456"> </form>
参考js里的内容,用python的dict表示f0的话有如下的伪代码:
f0={} f0["DDDDD"]=f1['DDDD'] f0["upass"]=calcMD5(pid+f1['upass']+calg)+calg+pid; f0["R1"]=ss f0["R2"]=1 f0["para"]=00 f0["0MKKey"]=123456
其中ss、pid、calg都是常量,f1['DDDD']、f1['upass']分别是用户输入的用户名和密码字符串
关键在于calcMD5的算法。
从函数名和函数本身来看,这个函数是MD5的一种实现。然而对js代码进行移植的过程中出现了一些问题:js和python的移位操作表现不同。
既然整个f0['upass']字段除了用户输入的密码以外,其它都是常量,完全可以用js计算出f0['upass'],python中只要保存这个字符串就行了。
检查cookies发现整个网页没有使用cookies。
登录后跳转到登出页面,分析登出页面发现,登出只需要访问某个特定的网页就行了。
于是整个思路很简单,pos登录服务器实现登录,get指定网页登出。实现代码如下:
importsys fromurllibimporturlencode fromurllib2importurlopen username="s10********" upass="6696a3***********************************" LOGIN="http://202.1**.***.***/" LOGOUT="http://202.1**.***.***/F.htm" defpost(url,data=None): ifdata: data=urlencode(data) response=urlopen(url,data) returnresponse.read() deflogin(): data={} data["DDDDD"]=username data["upass"]=upass data["R1"]=0 data["R2"]=1 data["para"]=00 data["0MKKey"]=123456 post(LOGIN,data) pass deflogout(): post(LOGOUT) defmain(argv): ifargv[0]in('login','in','i'): login() elifargv[0]in('logout','out','o'): logout() pass pass if__name__=='__main__': main(sys.argv[1:]);