webqq go语言的实现
最近开始学习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 main import ( "fmt" "os" "http" "net" "regexp" "crypto/md5" "hash" "strings" "encoding/hex" "io/ioutil" "bytes" "bufio" ) var mcookies = make(map[string] *http.Cookie)//保存cookie var qq string var pass string var ptwebqq string//cookie值登陆和后面用 var skey string//cookie值登陆和后面用 var clientid string="63690451"//随机取 var vfwebqq string //第二次返回的参数 var psessionid string //第二次登陆返回的参数 var refer string func 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"].Value skey=mcookies["skey"].Value fmt.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);//urlencode content = "r="+content;//post的数据 res := PostUrl(channelLoginUrl,refer,[]byte(content));//post re_twice:=string(res[:]) //第二次返回是个json格式,如下,我们要获取 psessionid vfwebqq值 /* {"retcode":0,"result":{"uin":526868457,"cip":1987728778,"index":1075,"port":40831,"status":"online","vfwebqq":"6c47630a8cd98902d38d919420ffb019141ba7f ebd6b8ce02b0b69d7b85e0ad2205c8f141a66f364","psessionid":"8368046764001d636f6e6e7365727665725f77656271714031302e3133342e362e31333800006023000005ee026e0 400e95f671f6d0000000a4058474d6430776c35476d000000286c47630a8cd98902d38d919420ffb019141ba7febd6b8ce02b0b69d7b85e0ad2205c8f141a66f364","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 first host := url.Host conn, err := net.Dial("tcp", host) checkError(err) // then wrap an HTTP client connection around it clientConn := http.NewClientConn(conn, nil) if clientConn == nil { fmt.Println("Can't build connection") os.Exit(1) } // define the additional HTTP header fields header := 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 request request := 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 request err = clientConn.Write(&request) checkError(err) // and get the response response, err := clientConn.Read(&request) checkError(err) if response.Status != "200 OK" { fmt.Println(response.Status) os.Exit(2) } //Set-cookie for 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_tutorial reader := response.Body result :=make([]byte,0) //我们一个byte取可以有效避免数据覆盖的问题,不过与整块读取略微慢点,暂且这样写吧 for { switch nr, _ := reader.Read(buf[:]); true { case nr < 0: goto a1 break case nr == 0:// EOF goto a1 break; 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 first host := url.Host conn, err := net.Dial("tcp", host) checkError(err) // then wrap an HTTP client connection around it clientConn := http.NewClientConn(conn, nil) if clientConn == nil { fmt.Println("Can't build connection") os.Exit(1) } // define the additional HTTP header fields header := 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 request request := 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 request err = clientConn.Write(&request) checkError(err) // and get the response response, err := clientConn.Read(&request) checkError(err) if response.Status != "200 OK" { fmt.Println(response.Status) } //Set-cookie for 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_tutorial reader := response.Body result :=make([]byte,0) //我们一个byte取可以有效避免数据覆盖的问题,不过与整块读取略微慢点,暂且这样写吧 for { switch nr, _ := reader.Read(buf[:]); true { case nr < 0: goto a2 break case nr == 0:// EOF goto a2 break; 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 }
相关推荐
go语言webqq简单实现go语言webqq简单实现
WebQQ 效果实现实例:超酷的webQQ桌面效果,桌面拖拽,桌面右键等。
本源码已经实现webQQ的大部分功能 熬了几个通宵终于做好了,里面实现的webQQ的大部分功能,而且全开源,适用中高级.net开发人员研究,主要是对 XML 的操作和ajax,还用了少量的JQ可以自由增加组,加好友等 数据库在...
仿WEBQQ,只实现了前端
ext 实现的webQQ 源码、应用、含数据库
JSP+Mysql 实现简易的 WebQQ
通过抓包分析WebQQ3.0协议做出的WebQQ客户端,开发工具Visual studio 2008,开发语言C#,此WebQQ客户端包括验证码获取,QQ登录,获取好友列表,获取在线好友列表,接收消息,发送消息等功能,基本上实现聊天需求。...
webqq 界面实现代码 html 直接运行 和现有版本完全一致 不需要装运行环境 不需要做其他配置 一键运行 和现有webqq 界面一样华丽
迷你WEBQQ
webqq2 协议分析和 qq 聊天机器人简单实现 本文档主要介绍了 webqq2 协议的分析和实现一个简单的 qq 聊天机器人。下面是对该协议的详细分析和实现步骤: 1. 首先,需要调用 ...
webQQ(实现webQQ的大部分功能)源码 熬了几个通宵终于做好了,里面实现的webQQ的大部分功能,而且全开源,适用中高级.net开发人员研究,主要是对 XML 的操作和ajax,还用了少量的JQ可以自由增加组,加好友等
此项目目前已停止维护,感谢大家四年来的一路陪伴】使用Perl语言(不会没关系)编写的smartqq/webqq客户端框架(非GUI),可通过插件提供基于HTTP协议的api接口供其他语言或系统调用Mojo-Webqq v2.2.7,一个api可以被...
仿WebQQ的桌面系统,纯JQuery制作,代码非常易理解 可马上上手进行二次开发
WebQQ协议.rar
webqq 源码 webqq仿制 webqq 源码 webqq仿制
webQQ源码.e
实现了网页QQ 的功能! 如果代码有问题 忘高手指点! 谢谢 本人QQ 471304128
jquery-----WebQQ桌面布局
asp版本的WEBQQ源代码,实现WEBQQ的功能
webqq MIni版登陆程序 webqq MIni版登陆程序webqq MIni版登陆程序webqq MIni版登陆程序