本文面向有一定基礎(chǔ),并能夠獨(dú)自分析語法,對編寫程序有興趣的讀者。文中所述的某些技術(shù)對其他論壇、郵箱、社區(qū)等均有效,而本文的重點(diǎn)則在于分析錯誤的能力。
來有些日子了,覺得是個學(xué)編程的好地方,但每次登陸總覺麻煩,因此有了編一個程序自動登陸論壇的想法。想法是好的,實(shí)現(xiàn)起來卻走了不少彎路,因此,便有了寫這篇文章的念頭,將我在編寫登陸程序的過程中曾經(jīng)出現(xiàn)過的問題全部總結(jié)一下,我深信,這篇文章必定會為大家喜歡,也一定會有很多人收藏的!(因?yàn)樵谖矣辛讼敕ㄖ?,幾乎還沒在網(wǎng)上找到一篇有關(guān)這方面的詳細(xì)資料,也許是我太菜了吧?。?/p>
在具體的代碼開始之前,我想有必要先交代一下有關(guān)Cookie及Session的問題。
現(xiàn)在幾乎安全性比較好的網(wǎng)站都使用了Cookie Or Session,前者是存放在本地電腦上的,能夠保存登陸信息并在下次登陸時不必再次輸入密碼,可以說是根據(jù)服務(wù)器上的代碼有目的性的產(chǎn)生;后者則在登陸及保持連接時有用,它的產(chǎn)生是隨機(jī)的僅相當(dāng)于一個臨時ID的作用。簡單來說,Cookie是長期存在的,相當(dāng)于服務(wù)器在你的電腦上留下的一個記號;而Session則只在登陸時有用,并會在保持連接時不斷發(fā)送,斷開連接之后,Session就不存在了,它的主要作用在于服務(wù)器一方使用Session來區(qū)分各用戶。
之所以只是簡單的說明一下,是因?yàn)樵谖移鸪醯拇a總是不斷失敗的時候,我曾經(jīng)誤以為Inet或WebBrowser不能與服務(wù)器進(jìn)行Cookie Or Session的對話,而事實(shí)上完全不是這樣的,因此讀者大可不必對Inet或WebBrowser疑慮重重了。相信這句話一定讓某些讀者大為放心,我自己便曾經(jīng)翻山越嶺去查找Cookie及Session的資料,甚至想到使用Winsock模擬發(fā)送了~。
**********************下面看看代碼**********************
“部件”中勾中Inet控件,放一個Inet、一個按鈕、兩個文本框在窗體上,兩個文本框的MultiLine屬性設(shè)置為True。然后在代碼窗口中添加上以下代碼:
Option Explicit
Dim URL As String
Dim Cookies As String
Dim a As Integer
Private Sub Command1_Click()
Dim stemp As String, pagecode As String
Dim strURL As String, strFormData As String
strURL = "http://www.csdn.net/member/logon.asp"
strFormData = "login_name=賬號&password=密碼"
Inet1.Execute strURL, "Post", strFormData
Do Until Inet1.StillExecuting = False '這里阻塞前面的Inet1,你可以將此Do取消了試一次
DoEvents
Loop
stemp = Inet1.GetChunk(1024)
Do While stemp <> ""
pagecode = pagecode + stemp
stemp = Inet1.GetChunk(1024)
Loop
Text2 = pagecode
End Sub
Private Sub Inet1_StateChanged(ByVal State As Integer)
Select Case State
Case 12
Text1.Text = Inet1.GetHeader
Case Else
End Select
End Sub
這便是我最初的代碼,不要問我這些代碼是從哪里來的,我所要說的一切便以這段代碼為起點(diǎn),因此我希望讀者能夠起碼知道這段代碼的基本意思(不要求全都讀懂,沒必要。)
Inet1_StateChanged用來得到服務(wù)器返回的文件頭,請讀者換上自己的賬號及密碼試運(yùn)行一次,便會發(fā)現(xiàn)返回的文件頭里既沒有Cookie也沒有Session的信息,而第二個文本框里面則返回的是“請輸入用戶名!”這樣的信息,這說明我們的登陸失敗了。
稍后我將說明這段代碼中的兩個致命的錯誤。
在此之前我首先解釋一下“l(fā)ogin_name=賬號&password=密碼”這兩個參數(shù)以及這個地址的由來。
這便要求具有一定的分析HTML的能力,當(dāng)然最好是自己寫過網(wǎng)頁并且了解服務(wù)器上網(wǎng)頁的工作機(jī)制??梢愿嬖V大家的是,這三個東西都是從CSDN的登陸頁面的源文件中分析出來的。具體怎么分析的我就不多嘴了,倒是那些還不能獨(dú)立分析HTML的讀者,我在這里要向你們推薦一個很有用的工具“Visual Sniffer”,它可以攔截通過網(wǎng)絡(luò)傳輸?shù)腡CP/IP/UDP/ICMP等數(shù)據(jù)包,利用這個工具你可以很輕松的得到這幾個參數(shù)。
現(xiàn)在我們用IE打開“http://www.csdn.net/member/login.asp”CSDN的登陸頁面,輸入你的賬號及密碼,先不要點(diǎn)“登陸”,將Visual Sniffer運(yùn)行起來,點(diǎn)一下“開始攔截”這個按鈕,再回到登陸頁面,點(diǎn)擊“登陸”,稍等片刻,登陸成功之后在Visual Sniffer上點(diǎn)一下“停止攔截”,現(xiàn)在你就可以找一下剛才IE到底向外發(fā)送了些什么東西。(建議你在做這些之前將多余的IE全都關(guān)掉,因?yàn)樘热羝渌麵E窗口也在發(fā)送數(shù)據(jù),你將會在Visual Sniffer受到不必要的干擾。)
注意現(xiàn)在在Visual Sniffer的左邊有很多“+”號,這些便是被攔截到的數(shù)據(jù),將它們一一展開,此時應(yīng)注意查看右邊的數(shù)據(jù),倘若第一行沒有“POST”這樣的字符,那便迅速換一個“+”號,這已經(jīng)是最快的找到向CSDN的服務(wù)器發(fā)送數(shù)據(jù)的方法了(我們的登陸是“POST”請求,如果看到的“GET”,那肯定不是)。請看實(shí)際的圖片:
雖然還是一頭霧水,但是比起剛開始的時候,我們已經(jīng)擁有了一個很重要的工具——“Visual Sniffer”!
不錯,或許已經(jīng)有朋友想到了,我們的代碼也是使用的HTTP協(xié)議,Visual Sniffer肯定也能攔截,只要再將代碼攔截一次,便能比較兩次POST的有什么不同的數(shù)據(jù)了。
果然,我們自己的代碼發(fā)送出去的數(shù)據(jù)比起IE的登陸窗口少了許多內(nèi)容。
現(xiàn)在先對發(fā)出去的文件頭稍加說明一下:
“Accept:”表示能夠收到的文件格式。
“Referer:”表示指向的文件地址。
“Accept_Language:”表示接受的語言。
“Host:”表示主機(jī)名。
有幾個不是很重要,因此這里就不多說了?,F(xiàn)在關(guān)鍵是比較這兩個POST出去的數(shù)據(jù)包有何異同。請注意看紫色部分,這些是我們的代碼沒有發(fā)送出去的內(nèi)容,而這兩處也正好刺中我們代碼中的錯誤!
“Content-Type: application/x-www-form-urlencoded”這是什么?趕快查資料!
回到代碼中“Inet1.Execute”的地方,將后面的東西全擦掉,按一下空格,可以看到,“Execute”有四個參數(shù),而我們只給出了三個,還有一個“InPutHeaders”參數(shù)沒有指明。
而恰恰是這個參數(shù)告訴服務(wù)器數(shù)據(jù)的解碼方式??!
明白了吧?我們不帶這個參數(shù)服務(wù)器便無法知道“l(fā)ogin_name=賬號&password=密碼”怎么解碼,從而誤以為用戶沒有輸入用戶名,那它當(dāng)然只能返回一個“請輸入用戶名!”這樣的信息了~
將代碼替換成
Inet1.Execute strURL, "Post", strFormData, "Content-Type: application/x-www-form-urlencoded "
再試一次,返回的是什么?
“保存時間有誤!”??????
我的第一反應(yīng)是:“有門兒,離成功不遠(yuǎn)了!”,起碼用戶名及密碼服務(wù)器都已經(jīng)接受了~而且第一反應(yīng)也告訴我,很可能是我少了一個參數(shù)!
現(xiàn)在我們再看一下圖片中第二個紫色圈起來的地方,這個地方有“Cookie”的字眼,而且與賬號密碼連在一起,這說明,這個地方也是服務(wù)器必須接受的參數(shù)!那么是什么參數(shù)呢?
讓我們再次打開http://www.csdn.net/member/logon.asp,相信CSDN的朋友們對下面的這副圖片已經(jīng)熟悉的不能再熟悉了吧~注意紅色圈起來的地方~
原來還有一個參數(shù),用來設(shè)置Cookie作用的時間!而這個參數(shù)我在分析源代碼時沒能分析出來~(主要是經(jīng)驗(yàn)不夠)
現(xiàn)在將strFormData = "login_name=賬號&password=密碼&cookietime=0&x=42&y=10"替換掉原來的內(nèi)容,再試一次~
Text1里面有返回的Cookie,Text2顯示正在登陸的頁面源代碼~
恭喜你~你登陸成功了~
小結(jié):參數(shù)是最重要的,尤其對網(wǎng)絡(luò)上的服務(wù)器發(fā)送請求時所傳輸?shù)膮?shù)名都不可能一樣,因此這一步便要求迅速而準(zhǔn)確地獲得參數(shù)名,幸而我們已經(jīng)有了一個很好的工具,從而得得已繞開復(fù)雜的分析源代碼的過程。