http 登录优购
2016-05-30 18:25
375 查看
package login import ( "crypto/tls" "fmt" "io/ioutil" "net/http" "net/url" "regexp" "strconv" "strings" ) func New() *Login2Yougou { return &Login2Yougou{nil, false, 0, nil} } type Login2Yougou struct { client *http.Client // client http isLogin bool // 是否成功登录 iSerialNumber uint64 // 流水号,初时值可以固定,但每次请求自增,服务器会效验 cookie []*http.Cookie // cookies 以便多个client复用 } //------------------------------------------------------------------------------ // 属性 func (this *Login2Yougou) SetCookies(cok []*http.Cookie) { this.cookie = cok } func (this *Login2Yougou) GetCookies() []*http.Cookie { return this.cookie } func (this *Login2Yougou) GetClient() *http.Client { return this.client } func (this *Login2Yougou) GetLoginResult() bool { return this.isLogin } func (this *Login2Yougou) GetSerialNumber() uint64 { num := this.iSerialNumber this.iSerialNumber += 1 // 下次请求流水号要自增1 return num } //------------------------------------------------------------------------------ // 操作 // 获取主页html 返回html字符串 func (this *Login2Yougou) getMainPage(url string) (ret string) { tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } this.client = &http.Client{Transport: tr} resp, err := this.client.Get(url) defer resp.Body.Close() // 获取失败 if err != nil { fmt.Println("error:", err) return ret } //fmt.Println(resp) // 获取成功 arr, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("error:", err) return } ret = string(arr) //this.cookie = resp.Cookies() this.SetCookies(resp.Cookies()) return ret } // 解析主页html 返回序列号,sKey,sValue,解析是否成功 func (this *Login2Yougou) parseMainPage(html string) (iSerialNumber uint64, sKey string, sValue string, err bool) { // 使用正则进行局部匹配 reg := regexp.MustCompile("<input type=\"hidden\" name=\".{5,20}\" value=\".{2,10}\" id=\"loginNonceId\"/>") // 匹配到结果集 arr := reg.FindStringSubmatch(html) for _, subXml := range arr { //fmt.Println(subXml) // 查询skey findPos := strings.Index(subXml, "name=\"") if findPos != -1 { findPos += len(string("name=\"")) _subXml := string(subXml[findPos:]) findpos2 := strings.Index(_subXml, "\"") if findpos2 != -1 { sKey = string(_subXml[:findpos2]) //fmt.Println(sKey) } } // 查询sValue findPos = strings.Index(subXml, "value=\"") if findPos != -1 { findPos += len(string("value=\"")) _subXml := string(subXml[findPos:]) findpos2 := strings.Index(_subXml, "\"") if findpos2 != -1 { sValue = string(_subXml[:findpos2]) //fmt.Println(sValue) } } } iSerialNumber = 1464312215280 if len(sKey) == 0 || len(sValue) == 0 { err = false return } err = true return } // 根据用户名密码登录 func (this *Login2Yougou) LoginYougou(userName string, passwd string) bool { shtml := this.getMainPage("https://passport.yougou.com/signin.jhtml?redirectURL=http://www.yougou.com/") if len(shtml) == 0 { fmt.Println("https 请求主页失败") return false } iSerialNumber, sKey, sValue, ret := this.parseMainPage(shtml) if ret == false { fmt.Println("获取流水号,键值对失败") return false } fmt.Println(iSerialNumber, sKey, sValue) //////////////////////////////////////////////////////////////////////////// // 进行login post loginUrl := "https://passport.yougou.com/my/procsignin.jhtml?callback=" + strconv.FormatUint(iSerialNumber, 10) fmt.Println(loginUrl) // 设置form form := make(url.Values) form.Set("username", userName) form.Set("password", passwd) form.Set("verifycode", "") form.Set("isVerify", "true") form.Set(sKey, sValue) form.Set("callback", "jsonp"+strconv.FormatUint(iSerialNumber, 10)) fmt.Println(form) // 添加request http info req, err := http.NewRequest("POST", loginUrl, strings.NewReader(form.Encode())) req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0") req.Header.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") req.Header.Add("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3") req.Header.Add("Content-Type", "application/x-www-form-urlencoded") req.Header.Add("X-Requested-With", "XMLHttpRequest") req.Header.Add("Connection", "Keep-Alive") req.Header.Add("Pragma", "no-cache") req.Header.Add("Cache-Control", "no-cache") // 复用之前的cookies for _, cok := range this.GetCookies() { req.AddCookie(cok) } fmt.Println(req) resp, err := this.client.Do(req) defer resp.Body.Close() if err != nil { fmt.Println("post form失败:", err.Error()) return false } arr, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("post form返回内容为空 api可能改变:", err.Error()) return false } fmt.Println(string(arr)) findPos := strings.Index(string(arr), "login_success") if findPos == -1 { fmt.Println("未能登录成功") return false } else { fmt.Println("恭喜你 登录成功") } this.isLogin = true return true }
main.go[主函数]
package main
import "fmt"
import "login"
func main() {
fmt.Println("主函数")
loginy := login.New()
loginy.LoginYougou("用户名", "密码")
}
相关文章推荐
- RPC failed; result=22, HTTP code = 411
- HTTP Header 属性列表
- nginx中http核心模块的配置指令2
- nginx中http核心模块的配置指令3
- nginx中http核心模块的配置指令4
- nginx中http的fastcgi模块的配置指令1
- 如何在 Linux 中快速地通过 HTTP 提供文件访问服务
- 深入HTTP head的使用详解
- Ruby程序中发送基于HTTP协议的请求的简单示例
- ASP 中使用 HTTP 协议发送参数详解
- C#基于socket模拟http请求的方法
- http www安全必备知识
- SQLSERVER 中GO的作用详解
- asp HTTP 500错误 常见问题分析
- http代理相关知识分析
- 在Node.js中使用HTTP上传文件的方法
- php错误提示failed to open stream: HTTP request failed!的完美解决方法