【背景】
折腾完毕:
后,接着,就是去把已经写的,通用函数,整理至自己的库函数crifanLib.go中了。
【折腾过程】
1.继续去参考,之前在:
中就学习的:
然后去新建对应的文件夹和文件。
2.然后再去build和install:
1 2 3 4 5 6 | E:\Dev_Root\go\src\code.google.com\p\crifanLib>go build E:\Dev_Root\go\src\code.google.com\p\crifanLib>go install E:\Dev_Root\go\src\code.google.com\p\crifanLib>ls crifanLib.go crifanLib.go.bak |
3.期间还遇到:
【已解决】go语言中导入另外一个库结果调用时出错:cannot refer to unexported name
4.最后,折腾结果为:
(1)目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | go pkg windows_amd64 code.google.com p crifanLib.a //after install, can see this file log4go.a //after install, can see this file src code.google.com p crifanLib crifanLib.go log4go ... EmulateLoginBaidu EmulateLoginBaidu.go |
(2)文件内容:
A. EmulateLoginBaidu.go(注意文件是UTF-8编码)内容如下::
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | /* * [File] * EmulateLoginBaidu.go * * [Function] * 【记录】用go语言实现模拟登陆百度 * * [Version] * 2013-09-21 * * [Contact] */ package main import ( "fmt" //"builtin" //"log" //"os" "runtime" "path" "strings" "time" //"io" //"io/ioutil" "net/http" //"net/http/cookiejar" //"net/url" //"sync" //"net/url" "regexp" //"bufio" //"bytes" ) import "code.google.com/p/log4go" //import "code.google.com/p/crifanLib/crifanLib" import "code.google.com/p/crifanLib" /*************************************************************************************************** Global Variables ***************************************************************************************************/ var gLogger log4go.Logger; var gCurCookies []*http.Cookie; /*************************************************************************************************** Functions ***************************************************************************************************/ // Get current file name, without suffix func getCurFilename() string { _, fulleFilename, _, _ := runtime.Caller( 0 ) //fmt.Println(fulleFilename) var filenameWithSuffix string filenameWithSuffix = path.Base(fulleFilename) //fmt.Println("filenameWithSuffix=", filenameWithSuffix) var fileSuffix string fileSuffix = path.Ext(filenameWithSuffix) //fmt.Println("fileSuffix=", fileSuffix) var filenameOnly string filenameOnly = strings.TrimSuffix(filenameWithSuffix, fileSuffix) //fmt.Println("filenameOnly=", filenameOnly) return filenameOnly } //do init before all others func initAll(){ gCurCookies = nil gLogger = crifanLib.InitLogger(getCurFilename() + ".log" ) } // //de-init for all // func deinitAll(){ // if(nil == gLogger) { // gLogger.Close(); // //os.Stdout.Sync() //try manually flush, but can not fix log4go's flush bug // gLogger = nil // } // } func main() { initAll() gLogger.Info( "============ 程序说明 ============" ); gLogger.Info( "功能:本程序是用来演示使用Java代码去实现模拟登陆百度" ); gLogger.Info( "注意事项:部分百度账户,在登陆时会出现:" ); gLogger.Info( "1.部分百度账户,在登陆时会出现:" ); gLogger.Info( "系统检测到您的帐号疑似被盗,存在安全风险。请尽快修改密码。" ); gLogger.Info( "此时,本程序,无法成功模拟登陆,请自行按照提示去修改密码后,就可以了。" ); //step1: access baidu url to get cookie BAIDUID gLogger.Info( "====== 步骤1:获得BAIDUID的Cookie ======" ) gLogger.Debug( "baiduMainUrl=%s" , baiduMainUrl) respHtml := crifanLib.GetUrlRespHtml(baiduMainUrl, nil) gLogger.Debug( "respHtml=%s" , respHtml) crifanLib.DbgPrintCookies(crifanLib.GetCurCookies()) //check cookie var bGotCookieBaiduid = false ; //var cookieNameListToCheck []string = ["BAIDUID"] //toCheckCookieNameList := [1]string{"BAIDUID"} toCheckCookieNameList := []string{ "BAIDUID" } toCheckCookieNum := len(toCheckCookieNameList) gLogger.Debug( "toCheckCookieNum=%d" , toCheckCookieNum) gCurCookies = crifanLib.GetCurCookies() curCookieNum := len(gCurCookies) gLogger.Debug( "curCookieNum=%d" , curCookieNum) for i := 0 ; i < toCheckCookieNum; i++ { toCheckCkName := toCheckCookieNameList[i]; gLogger.Debug( "[%d]toCheckCkName=%s" , i, toCheckCkName) for j := 0 ; j < curCookieNum; j++{ curCookie := gCurCookies[j] if (strings.EqualFold(toCheckCkName, curCookie.Name)){ bGotCookieBaiduid = true ; break ; } } } if bGotCookieBaiduid { gLogger.Info( "Found cookie BAIDUID" ); } else { gLogger.Info( "Not found cookie BAIDUID" ); } //step2: login, pass paras, extract resp cookie gLogger.Info( "====== 步骤2:提取login_token ======" ); bExtractTokenValueOK := false strLoginToken := "" var getApiRespHtml string; if bGotCookieBaiduid{ getApiRespHtml = crifanLib.GetUrlRespHtml(getapiUrl, nil); gLogger.Debug( "getApiRespHtml=%s" , getApiRespHtml); crifanLib.DbgPrintCookies(crifanLib.GetCurCookies()) //bdPass.api.params.login_token='278623fc5463aa25b0189ddd34165592'; //use regex to extract login_token //【记录】go语言中用正则表达式查找某个值 loginTokenP, _ := regexp.Compile(`bdPass\.api\.params\.login_token= '(?P<loginToken>\w+)' ;`) //loginToken := loginTokenP.FindString(getApiRespHtml); //loginToken := loginTokenP.FindSubmatch(getApiRespHtml); foundLoginToken := loginTokenP.FindStringSubmatch(getApiRespHtml); gLogger.Debug( "foundLoginToken=%s" , foundLoginToken); if nil != foundLoginToken { strLoginToken = foundLoginToken[ 1 ] //tmp go regexp not support named group, so use index here gLogger.Info( "found bdPass.api.params.login_token=%s" , strLoginToken); bExtractTokenValueOK = true ; } else { gLogger.Warn( " not found login_token from html=%s" , getApiRespHtml); } } //step3: verify returned cookies bLoginBaiduOk := false ; if bGotCookieBaiduid && bExtractTokenValueOK { gLogger.Info( "======步骤3:登陆百度并检验返回的Cookie ======" ); postDict := map[string]string{} //postDict["ppui_logintime"] = "" postDict[ "charset" ] = "utf-8" //postDict["codestring"] = "" postDict[ "token" ] = strLoginToken postDict[ "isPhone" ] = "false" postDict[ "index" ] = "0" //postDict["u"] = "" //postDict["safeflg"] = "0" postDict[ "staticpage" ] = staticPageUrl postDict[ "loginType" ] = "1" postDict[ "tpl" ] = "mn" postDict[ "callback" ] = "parent.bdPass.api.login._postCallback" //【已解决】go语言中获得控制台输入的字符串 strBaiduUsername := "" strBaiduPassword := "" gLogger.Info( "Plese input:" ) gLogger.Info( "Baidu Username:" ) _, err1 := fmt.Scanln(&strBaiduUsername) if nil == err1 { gLogger.Debug( "strBaiduUsername=%s" , strBaiduUsername) } gLogger.Info( "Baidu Password:" ) _, err2 := fmt.Scanln(&strBaiduPassword) if nil == err2 { gLogger.Debug( "strBaiduPassword=%s" , strBaiduPassword) } postDict[ "username" ] = strBaiduUsername postDict[ "password" ] = strBaiduPassword postDict[ "verifycode" ] = "" postDict[ "mem_pass" ] = "on" gLogger.Debug( "postDict=%s" , postDict) loginBaiduRespHtml := crifanLib.GetUrlRespHtml(baiduMainLoginUrl, postDict); gLogger.Debug( "loginBaiduRespHtml=%s" , loginBaiduRespHtml) crifanLib.DbgPrintCookies(crifanLib.GetCurCookies()); //check resp cookies exist or not cookieNameDict := map[string]bool{ "BDUSS" : false , "PTOKEN" : false , "STOKEN" : false , //"SAVEUSERID": false, //be deleted } gCurCookies = crifanLib.GetCurCookies() for cookieName, _ := range cookieNameDict { for _, singleCookie := range gCurCookies { //if(strings.EqualFold(cookieName, singleCookie.Name)){ if cookieName == singleCookie.Name { cookieNameDict[cookieName] = true ; gLogger.Debug( "Found cookie %s" , cookieName) } } } gLogger.Debug( "After check resp cookie, cookieNameDict=%s" , cookieNameDict) bAllCookiesFound := true for _, bIsExist := range cookieNameDict { bAllCookiesFound = bAllCookiesFound && bIsExist } bLoginBaiduOk = bAllCookiesFound if (bLoginBaiduOk) { gLogger.Info( "成功模拟登陆百度首页!" ); } else { gLogger.Info( "模拟登陆百度首页 失败!" ); gLogger.Info( "所返回的HTML源码为:" + loginBaiduRespHtml); } } // deinitAll() //【workaround】go语言中用log4go输出信息时有bug:只输出部分信息,甚至是无任何输出 time.Sleep( 100 * time.Millisecond) } |
B. crifanLib.go(注意文件是UTF-8编码)内容如下:
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | /* * [File] * crifanLib..go * * [Function] * 【记录】在用go语言成功模拟登陆百度后把相关函数整理至自己的go语言的库函数:crifanLib.go * https://www.crifan.com/after_use_go_language_emulate_login_baidu_arrage_common_func_to_crifanlib_go * * [Version] * 2013-09-21 * * [Contact] */ package crifanLib import ( //"fmt" //"log" "os" //"runtime" //"path" //"strings" "time" //"io" "io/ioutil" "net/http" "net/http/cookiejar" "net/url" //"sync" //"net/url" //"regexp" //"bufio" "bytes" ) //import l4g "log4go.googlecode.com/hg" //import l4g "code.google.com/p/log4go" import "code.google.com/p/log4go" /*************************************************************************************************** Global Variables ***************************************************************************************************/ var gCurCookies []*http.Cookie; var gCurCookieJar *cookiejar.Jar; var gLogger log4go.Logger; /*************************************************************************************************** Private Functions ***************************************************************************************************/ //init for crifanLib func init(){ gCurCookies = nil gCurCookieJar,_ = cookiejar.New(nil) gLogger = nil //InitLogger() // caller should manually call this } // //de-init for all // func deinitAll(){ // gCurCookies = nil // if(nil == gLogger) { // gLogger.Close(); // //os.Stdout.Sync() //try manually flush, but can not fix log4go's flush bug // gLogger = nil // } // } /*************************************************************************************************** Public Functions ***************************************************************************************************/ //init for logger func InitLogger(logFilename string) log4go.Logger { //var filenameOnly string = GetCurFilename() //var logFilename string = filenameOnly + ".log"; //gLogger = log4go.NewLogger() //gLogger = make(log4go.Logger) //for console //gLogger.AddFilter("stdout", log4go.INFO, log4go.NewConsoleLogWriter()) gLogger = log4go.NewDefaultLogger(log4go.INFO) //for log file if _, err := os.Stat(logFilename); err == nil { //fmt.Printf("found old log file %s, now remove it\n", logFilename) os.Remove(logFilename) } //gLogger.AddFilter("logfile", log4go.FINEST, log4go.NewFileLogWriter(logFilename, true)) //gLogger.AddFilter("logfile", log4go.FINEST, log4go.NewFileLogWriter(logFilename, false)) gLogger.AddFilter( "log" , log4go.FINEST, log4go.NewFileLogWriter(logFilename, false )) gLogger.Debug( "Current time is : %s" , time.Now().Format( "15:04:05 MST 2006/01/02" )) return gLogger } // //get current logger // func GetCurLogger() log4go.Logger { // return gLogger // } //get url response html func GetUrlRespHtml(strUrl string, postDict map[string]string) string{ gLogger.Debug( "in getUrlRespHtml, strUrl=%s" , strUrl) gLogger.Debug( "postDict=%s" , postDict) var respHtml string = "" ; httpClient := &http.Client{ //Transport:nil, //CheckRedirect: nil, Jar:gCurCookieJar, } var httpReq *http.Request //var newReqErr error if nil == postDict { gLogger.Debug( "is GET" ) //httpReq, newReqErr = http.NewRequest("GET", strUrl, nil) httpReq, _ = http.NewRequest( "GET" , strUrl, nil) // ... //httpReq.Header.Add("If-None-Match", `W/"wyzzy"`) } else { //【记录】go语言中实现http的POST且传递对应的post data gLogger.Debug( "is POST" ) postValues := url.Values{} for postKey, PostValue := range postDict{ postValues.Set(postKey, PostValue) } gLogger.Debug( "postValues=%s" , postValues) postDataStr := postValues.Encode() gLogger.Debug( "postDataStr=%s" , postDataStr) postDataBytes := [] byte (postDataStr) gLogger.Debug( "postDataBytes=%s" , postDataBytes) postBytesReader := bytes.NewReader(postDataBytes) //httpReq, newReqErr = http.NewRequest("POST", strUrl, postBytesReader) httpReq, _ = http.NewRequest( "POST" , strUrl, postBytesReader) //httpReq.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") httpReq.Header.Add( "Content-Type" , "application/x-www-form-urlencoded" ) } httpResp, err := httpClient.Do(httpReq) // ... //httpResp, err := http.Get(strUrl) //gLogger.Info("http.Get done") if err != nil { gLogger.Warn( "http get strUrl=%s response error=%s\n" , strUrl, err.Error()) } gLogger.Debug( "httpResp.Header=%s" , httpResp.Header) gLogger.Debug( "httpResp.Status=%s" , httpResp.Status) defer httpResp.Body.Close() // gLogger.Info("defer httpResp.Body.Close done") body, errReadAll := ioutil.ReadAll(httpResp.Body) //gLogger.Info("ioutil.ReadAll done") if errReadAll != nil { gLogger.Warn( "get response for strUrl=%s got error=%s\n" , strUrl, errReadAll.Error()) } //gLogger.Debug("body=%s\n", body) //gCurCookies = httpResp.Cookies() //gCurCookieJar = httpClient.Jar; gCurCookies = gCurCookieJar.Cookies(httpReq.URL); //gLogger.Info("httpResp.Cookies done") //respHtml = "just for test log ok or not" respHtml = string(body) //gLogger.Info("httpResp body []byte to string done") return respHtml } //get current http cookies func GetCurCookies() []*http.Cookie { return gCurCookies } //print http cookies func DbgPrintCookies(httpCookies []*http.Cookie) { if nil != httpCookies { var cookieNum int = len(httpCookies); gLogger.Debug( "cookieNum=%d" , cookieNum) for i := 0 ; i < cookieNum; i++ { var curCk *http.Cookie = httpCookies[i]; gLogger.Debug( "------ Cookie [%d]------" , i) gLogger.Debug( "Name\t\t=%s" , curCk.Name) gLogger.Debug( "Value\t=%s" , curCk.Value) gLogger.Debug( "Path\t\t=%s" , curCk.Path) gLogger.Debug( "Domain\t=%s" , curCk.Domain) gLogger.Debug( "Expires\t=%s" , curCk.Expires) gLogger.Debug( "RawExpires\t=%s" , curCk.RawExpires) gLogger.Debug( "MaxAge\t=%d" , curCk.MaxAge) gLogger.Debug( "Secure\t=%t" , curCk.Secure) gLogger.Debug( "HttpOnly\t=%t" , curCk.HttpOnly) gLogger.Debug( "Unparsed\t=%s" , curCk.Unparsed) gLogger.Debug( "Raw\t\t=%s" , curCk.Raw) } } } |
(3)使用方法:
A。先去编译和安装crifanLib.go
1 2 3 4 5 | E:\Dev_Root\go\src\code.google.com\p\crifanLib>go build E:\Dev_Root\go\src\code.google.com\p\crifanLib>go install E:\Dev_Root\go\src\code.google.com\p\crifanLib> |
B。运行EmulateLoginBaidu.go即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | E:\Dev_Root\go\src\EmulateLoginBaidu>go run EmulateLoginBaidu.go [09/21/13 21:51:04] [INFO] ============ 程序说明 ============ [09/21/13 21:51:04] [INFO] 功能:本程序是用来演示使用Java代码去实现模拟登陆百度 [09/21/13 21:51:04] [INFO] 注意事项:部分百度账户,在登陆时会出现: [09/21/13 21:51:04] [INFO] 1.部分百度账户,在登陆时会出现: [09/21/13 21:51:04] [INFO] 系统检测到您的帐号疑似被盗,存在安全风险。请尽快修改密码。 [09/21/13 21:51:04] [INFO] 此时,本程序,无法成功模拟登陆,请自行按照提示去修改密码后,就可以了。 [09/21/13 21:51:04] [INFO] ====== 步骤1:获得BAIDUID的Cookie ====== [09/21/13 21:51:04] [INFO] Found cookie BAIDUID [09/21/13 21:51:04] [INFO] ====== 步骤2:提取login_token ====== [09/21/13 21:51:05] [INFO] found bdPass.api.params.login_token=23a85f1cdf730fb8ee8c1a7ac0b563b0 [09/21/13 21:51:05] [INFO] ======步骤3:登陆百度并检验返回的Cookie ====== [09/21/13 21:51:05] [INFO] Plese input: [09/21/13 21:51:05] [INFO] Baidu Username: xxxxxx [09/21/13 21:51:10] [INFO] Baidu Password: yyyyyy [09/21/13 21:51:12] [INFO] 成功模拟登陆百度首页! |
C。当前的EmulateLoginBaidu.go所在目录下,可以生成的对应的log文件:EmulateLoginBaidu.log
且每次运行,之前旧的log文件会删除掉,会新生成对应的log文件的。
5.目前已把对应的库文件:
crifanLib.go
放到之前的crifanLib中了。
详见:
【总结】
go中弄个package,也还是有点麻烦的。。。
转载请注明:在路上 » 【记录】在用go语言成功模拟登陆百度后把相关函数整理至自己的go语言的库函数:crifanLib.go