webqq go語言的實現

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。最近開始學習go語言,覺得非常有趣,便從http入手,寫了個web掛機程式。適用go版本r59-201108最新版本,低版本編譯通不過。
// webQQ.go/* *GO語言討論群:102319854 *GO語言官網:www.golang.org *作者: 不死爬蟲 *首頁: http://www.gososo.org http://www.daohang361.com/news/index.html *見證的軌跡 *亂碼的解決方案 *1、dos執行chcp 65001 //修改字碼頁為utf-8,否則無法通過編譯  *2、修改dos視窗字型為Lucida Console,否則顯示的字元為亂碼  *http://bbs.golang-china.org/viewtopic.php?f=4&t=8&start=10#p93 *  chcp 命令: *  chcp 65001  就是換成UTF-8字碼頁,在命令列標題列上點擊右鍵,選擇"屬性"->"字型",將字型修改為True Type字型"Lucida Console",然後點擊確定將屬性應用到當前視窗 *  chcp 936 可以換回預設的GBK *  chcp 437 是美國英語 */package mainimport ("fmt""os""http""net""regexp""crypto/md5" "hash" "strings""encoding/hex""io/ioutil""bytes""bufio")var mcookies = make(map[string] *http.Cookie)//儲存cookievar qq stringvar pass stringvar ptwebqq string//cookie值登陸和後面用var skey string//cookie值登陸和後面用var clientid string="63690451"//隨機取var vfwebqq string     //第二次返回的參數var psessionid string //第二次登陸返回的參數var refer stringfunc main() {fmt.Println("If you run this First time,Please run 'chcp 65001' in then cmd ,then set front 'Lucida Console'")fmt.Println("And run 'chcp 936 to back default'")if len(os.Args) != 3 {                fmt.Println("Usage: ", os.Args[0], "365183440 pass")               in := bufio.NewReader(os.Stdin)               line, _ := in.ReadString('\n')               qq=strings.Split(line," ")[0]               pass=strings.Split(line," ")[1]               pass=strings.TrimSpace(pass)     }else{    qq   = os.Args[1];    pass =os.Args[2];}fmt.Println("qq:"+qq+"pass:"+pass)refer="http://web2-b.qq.com/proxy.html"s:=getUrl("http://ptlogin2.qq.com:80/check?appid=1003903&uin="+qq,refer);var r=string(s[0:len(s)])fmt.Println(r)var checkType string=""re,_:=regexp.Compile("([^//']*)")s2:=re.FindAllString(r,-1)checkType=s2[3]fmt.Println("checkType:"+checkType)var checkcode string=""checkImg:    if strings.Index(checkType,"!")==0{fmt.Println("Not Need checkcode")checkcode=checkType; }else{fmt.Println("Need checkcode")checkcode=getImg("http://captcha.qq.com:80/getimage?aid=1003903&uin="+qq+"&vc_type="+checkType,refer)}fmt.Println("checkcode:"+checkcode)//接下來開始登陸了//第1次登陸    loginUrl := "http://ptlogin2.qq.com:80/login?u="+qq+"&" +"p=" +GetCryPass(pass, checkcode)+"&verifycode="+checkcode+"&remember_uin=1&aid=1003903" +"&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html%3Fstrong%3Dtrue" +"&h=1&ptredirect=0&ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert";rb:=getUrl(loginUrl,refer)var loginS string=string(rb[:])fmt.Println(loginS)if strings.Index(loginS,"成功")>0{fmt.Println("第一次登陸成功!")}else if  strings.Index(loginS,"驗證碼有誤")>0{fmt.Println("驗證碼有誤!重新擷取驗證碼圖片")goto checkImg}else if  strings.Index(loginS,"密碼有誤")>0{fmt.Println("密碼有誤!")os.Exit(0)}else{fmt.Println("未知錯誤!")os.Exit(0)}ptwebqq=mcookies["ptwebqq"].Valueskey=mcookies["skey"].Valuefmt.Println("skey:"+skey)fmt.Println("ptwebqq:"+ptwebqq)//再次登陸,只有這次登陸,才算真正登陸qq,這個時候,如果你qq已經登陸,會把你的qq踢下線,而且此次登陸才算上線    channelLoginUrl := "http://d.web2.qq.com:80/channel/login2";    content := "{\"status\":\"\",\"ptwebqq\":\""+ptwebqq+"\",\"passwd_sig\":\"\",\"clientid\":\""+clientid+"\"}";content = urlEncode(content);//urlencodecontent = "r="+content;//post的資料res := PostUrl(channelLoginUrl,refer,[]byte(content));//postre_twice:=string(res[:]) //第二次返回是個json格式,如下,我們要擷取 psessionid vfwebqq值/*{"retcode":0,"result":{"uin":526868457,"cip":1987728778,"index":1075,"port":40831,"status":"online","vfwebqq":"6c47630a8cd98902d38d919420ffb019141ba7febd6b8ce02b0b69d7b85e0ad2205c8f141a66f364","psessionid":"8368046764001d636f6e6e7365727665725f77656271714031302e3133342e362e31333800006023000005ee026e0400e95f671f6d0000000a4058474d6430776c35476d000000286c47630a8cd98902d38d919420ffb019141ba7febd6b8ce02b0b69d7b85e0ad2205c8f141a66f364","user_state":0,"f":0}}*/   fmt.Print(re_twice)   re,_=regexp.Compile("(vfwebqq\":\")([^\"]*)(\")")   s2=re.FindStringSubmatch(re_twice)   vfwebqq=s2[2];   re,_=regexp.Compile("(psessionid\":\")([^\"]*)(\")")   s2=re.FindStringSubmatch(re_twice)   psessionid=s2[2]   fmt.Println("psessionid:"+psessionid)   fmt.Println("vfwebqq:"+vfwebqq)   if len(vfwebqq)==0||len(psessionid)==0{   fmt.Println("登陸失敗");   os.Exit(0)   }   //到此登陸成功  調用poll訊息函數   poll()}func urlEncode(urlin string) string{    return http.URLEscape(urlin)}func poll(){    var pollUrl string="http://d.web2.qq.com:80/channel/poll2?clientid="+clientid+"&psessionid="+psessionid    for {    fmt.Println("擷取訊息......................................")    fmt.Println("Loop Get Message ......................................")       s:=getUrl(pollUrl,refer);       fmt.Println(string(s[:]))    }}/* *擷取驗證碼圖片,並且返回輸入驗證碼 */func getImg(urlin string ,refer string) string{imgByte:=getUrl(urlin,refer)fmt.Print("write img begin and the img length is:")    fmt.Println(len(imgByte))    err2 := ioutil.WriteFile("d:/aa.jpg", imgByte,0)    if err2 != nil { fmt.Println(err2)return ""} fmt.Println("請開啟檔案:d:/aa.jpg 並輸入驗證碼斷行符號");fmt.Println("Need CheckCode Open :d:/aa.jpp input CheckCode"); var line string     _, err := fmt.Scanln(&line)     if err!=nil{return ""}return line}/* *帶cookie擷取url */func getUrl(urlin string ,refer string)([]byte){url, err := http.ParseURL(urlin)checkError(err)// build a TCP connection firsthost := url.Hostconn, err := net.Dial("tcp", host)    checkError(err)// then wrap an HTTP client connection around itclientConn := http.NewClientConn(conn, nil)if clientConn == nil {fmt.Println("Can't build connection")os.Exit(1)}// define the additional HTTP header fieldsheader := map[string][] string {"Accept":{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*,q=0.8"},"Accept-Language":{"zh-cn,zh;q=0.5"},"Accept-Charset": {"UTF-8,utf-8;q=0.7,*;q=0.7"},"Connection":{"keep-alive"},"Referer": {refer},"User-Agent":{"Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0"} ,}// and build the requestrequest := http.Request{Method: "GET", URL: url, Header: header}for _, value := range mcookies {request.AddCookie(value)}dump, _ := http.DumpRequest(&request, false)fmt.Println(string(dump))// send the requesterr = clientConn.Write(&request)checkError(err)// and get the responseresponse, err := clientConn.Read(&request)checkError(err)if response.Status != "200 OK" {fmt.Println(response.Status)os.Exit(2)}//Set-cookiefor i:=0;i<len(response.Cookies());i++{mcookies[response.Cookies()[i].Name]=response.Cookies()[i]}const NBUF = 1      var buf =make([]byte,NBUF) //http://code.google.com/p/golang-china/wiki/go_tutorialreader := response.Bodyresult :=make([]byte,0)//我們一個byte取可以有效避免資料覆蓋的問題,不過與整塊讀取略微慢點,暫且這樣寫吧 for {  switch nr, _ := reader.Read(buf[:]); true {  case nr < 0:    goto a1   break     case nr == 0:// EOF              goto a1break;             case nr > 0:     result=append(result,buf[0])          } }a1:return result[0:len(result)];}/* *帶cookie post */func PostUrl(urlin string ,refer string,sendBytes []byte)([]byte){url, err := http.ParseURL(urlin)checkError(err)// build a TCP connection firsthost := url.Hostconn, err := net.Dial("tcp", host)    checkError(err)// then wrap an HTTP client connection around itclientConn := http.NewClientConn(conn, nil)if clientConn == nil {fmt.Println("Can't build connection")os.Exit(1)}// define the additional HTTP header fieldsheader := map[string][] string {"Accept":{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*,q=0.8"},"Accept-Language":{"zh-cn,zh;q=0.5"},"Accept-Charset": {"UTF-8,utf-8;q=0.7,*;q=0.7"},"Content-Type":{"application/x-www-form-urlencoded"}   ,"Connection":{"keep-alive"},"Transfer-Encoding":{"chunked"},"Referer": {refer},"User-Agent":{"Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0"} ,}// and build the requestrequest := http.Request{Method: "POST", URL: url, Header: header}request.ContentLength= (int64)(len(sendBytes))for _, value := range mcookies {        request.AddCookie(value)}request.Body= &ClosingBuffer{bytes.NewBuffer(sendBytes)}dump, _ := http.DumpRequest(&request, false)fmt.Println(string(dump))// send the requesterr = clientConn.Write(&request)checkError(err)// and get the responseresponse, err := clientConn.Read(&request)checkError(err)if response.Status != "200 OK" {fmt.Println(response.Status)}//Set-cookiefor i:=0;i<len(response.Cookies());i++{mcookies[response.Cookies()[i].Name]=response.Cookies()[i]}const NBUF = 1      var buf =make([]byte,NBUF) //http://code.google.com/p/golang-china/wiki/go_tutorialreader := response.Bodyresult :=make([]byte,0)//我們一個byte取可以有效避免資料覆蓋的問題,不過與整塊讀取略微慢點,暫且這樣寫吧 for {  switch nr, _ := reader.Read(buf[:]); true {  case nr < 0:    goto a2   break     case nr == 0:// EOF              goto a2break;             case nr > 0:     result=append(result,buf[0])          } }a2:return result[0:len(result)];}func checkError(err os.Error) {        if err != nil {                fmt.Println("Fatal error ", err.String())                //os.Exit(1)        }}/* *webqq加密方式 */func GetCryPass(pass string,code string) string{cryPss_3:=Getmd5_3(pass)cryPss_3=strings.ToUpper(hex.EncodeToString([]byte(cryPss_3)))+strings.ToUpper(code)r:=Getmd5(cryPss_3)return strings.ToUpper(hex.EncodeToString(r[0:len(r)]))}func Getmd5(original string) []byte {       var h hash.Hash = md5.New()       h.Write([]byte(original))       //fmt.Printf("%x\n", h.Sum()) return  h.Sum() } func Getmd5_3(in string) string{cry :=Getmd5(in)var r string=string(cry[0:len(cry)])cry =Getmd5(r)r=string(cry[0:len(cry)])cry =Getmd5(r)r=string(cry[0:len(cry)])return r }//實現io.ReadCloser介面type ClosingBuffer struct {        *bytes.Buffer}func (cb *ClosingBuffer) Close() (err os.Error) {        //we don't actually have to do anything here, since the buffer is//just some data in memory        //and the error is initialized to no-error        return}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.