最近都在学习golang的内容,今天写了点东西。
学习是基于网上的一些文章。不过功能是全新的
1)实现golang请求Get
2)实现post登陆
3) 实现web上传(基于pp.sohu.com)
代码实现:
package main import ( "base" "bytes" "fmt" "io" "io/ioutil" "log" "mime/multipart" "net/http" "net/http/cookiejar" "net/url" "os" "regexp" "strings" ) var gCurCookies []*http.Cookie var gCurCookieJar *cookiejar.Jar var logger *log.Logger /*UploadBodyEle struct --ad36e31ab0e27a44e9038057dc8d0a39aceb12b26f27fd6d375148e6b81a Content-Disposition: form-data; name="Filename" test.jpg */ type UploadBodyEle struct { boundary string key string value string } /* Use these info to construct the whole upload body string */ type UploadBodyInfo struct { eleMap map[string]string boundary string fileContent string } func initAll() { gCurCookies = nil gCurCookieJar, _ = cookiejar.New(nil) logg := base.NewLogger("log", "log.") logger = logg.Log() } func ReadUploadFile(filename string) string { buf := new(bytes.Buffer) w := multipart.NewWriter(buf) fw, err := w.CreateFormFile("file", filename) if err != nil { fmt.Println("c") } fd, err := os.Open(filename) defer fd.Close() if err != nil { fmt.Println("d") } _, err = io.Copy(fw, fd) if err != nil { fmt.Println("e") } w.Close() return buf.String() } func ConstructUploadBodyEleStr(ele *UploadBodyEle) string { return fmt.Sprintf("--%s\nContent-Disposition: form-data; name=\"%s\"\n\n%s\n", ele.boundary, ele.key, ele.value) } func ConstructUploadBodyStr(info *UploadBodyInfo) string { var str string for _key, _value := range info.eleMap { uploadbodyele := &UploadBodyEle{ boundary: info.boundary, key: _key, value: _value, } str += ConstructUploadBodyEleStr(uploadbodyele) } str += fmt.Sprintf("%s\n", info.fileContent) return str } func ConstructUploadReq(strUrl string, postDict map[string]string, filename string) *http.Request{ var httpReq *http.Request /*------------------------Content----------------------------*/ file_content := ReadUploadFile(filename) info := &UploadBodyInfo{ eleMap: postDict, boundary: file_content[2:strings.Index(file_content, "\n")], fileContent: file_content, } postDataStr := ConstructUploadBodyStr(info) postBytesReader := bytes.NewReader([]byte(postDataStr)) httpReq, _ = http.NewRequest("POST", strUrl, postBytesReader) /*------------------------Head----------------------------*/ httpReq.Header.Add("Content-Type", fmt.Sprintf("multipart/form-data; boundary=%s", info.boundary)) return httpReq } func getUrlRespHtml(httpClient *http.Client, strUrl string, postDict map[string]string, filename string) string { var httpReq *http.Request if nil == postDict { logger.Println("---------------is GET------------------") httpReq, _ = http.NewRequest("GET", strUrl, nil) httpReq.Header.Set("Accept", "application/json, text/javascript, */*; q=0.01") } else { if filename == "" { logger.Println("---------------is POST------------------") postValues := url.Values{} for postKey, PostValue := range postDict { postValues.Set(postKey, PostValue) } postDataStr := postValues.Encode() postBytesReader := bytes.NewReader([]byte(postDataStr)) httpReq, _ = http.NewRequest("POST", strUrl, postBytesReader) httpReq.Header.Add("Content-Type", "application/x-www-form-urlencoded") } else { logger.Println("---------------is POST Upload------------------") httpReq = ConstructUploadReq(strUrl, postDict, filename) } } httpResp, err := httpClient.Do(httpReq) if err != nil { logger.Println("http get strUrl=%s response error=%s", strUrl, err.Error()) } //logger.Println("httpResp.Status : %s", httpResp.Status) defer httpResp.Body.Close() body, errReadAll := ioutil.ReadAll(httpResp.Body) if errReadAll != nil { logger.Println("get response for strUrl=%s got error=%s\n", strUrl, errReadAll.Error()) } gCurCookies = gCurCookieJar.Cookies(httpReq.URL) respHtml := string(body) return respHtml } func PrintCurCookies() { var cookieNum int = len(gCurCookies) logger.Println("cookieNum=%d", cookieNum) for i := 0; i < cookieNum; i++ { var curCk *http.Cookie = gCurCookies[i] logger.Println("------ Cookie [%d]------", i) logger.Println("Name\t\t=%s", curCk.Name) logger.Println("Value\t=%s", curCk.Value) logger.Println("Path\t\t=%s", curCk.Path) logger.Println("Domain\t=%s", curCk.Domain) logger.Println("Expires\t=%s", curCk.Expires) logger.Println("RawExpires\t=%s", curCk.RawExpires) logger.Println("MaxAge\t=%d", curCk.MaxAge) logger.Println("Secure\t=%t", curCk.Secure) logger.Println("HttpOnly\t=%t", curCk.HttpOnly) logger.Println("Raw\t\t=%s", curCk.Raw) logger.Println("Unparsed\t=%s", curCk.Unparsed) } } func main() { initAll() httpClient := &http.Client{ Jar: gCurCookieJar, } //-------------------------------------------页面分割线------------------------------------------ postDict := map[string]string{} postDict["appid"] = "9998" postDict["persistentcookie"] = "0" postDict["b"] = "7" postDict["w"] = "1440" postDict["pwdtype"] = "1" postDict["v"] = "27" postDict["isSLogin"] = "1" postDict["ru"] = "https://passport.sohu.com/user/tologin" postDict["domain"] = "sohu.com" postDict["loginSuccessCallFunction"] = "postLoginSuccessCall" postDict["loginFailCallFunction"] = "postLoginFailCall" //strUsername := "" //strPassword := "" //logger.Println("Plese input:") //logger.Println("Username:") //_, err1 := fmt.Scanln(&strUsername) //if nil == err1 { // logger.Println("strUsername=%s", strUsername) //} //logger.Println("Password:") //_, err2 := fmt.Scanln(&strPassword) //if nil == err2 { // logger.Println("strPassword=%s", strPassword) //} //postdict["userid"] = strusername //postdict["password"] = strpassword postDict["userid"] = "pengnenghui04@sohu.com" postDict["password"] = "1775520214" logger.Println("postDict=%s", postDict) mainLoginUrl := "https://passport.sohu.com/user/login" loginRespHtml := getUrlRespHtml(httpClient, mainLoginUrl, postDict,"") logger.Println("loginRespHtml=%s", loginRespHtml) PrintCurCookies() //-------------------------------------------页面分割线------------------------------------------ toUrl_1 := "http://pp.sohu.com/folders" toRespHtml_1 := getUrlRespHtml(httpClient, toUrl_1, nil, "") logger.Println("toRespHtml=%s", toRespHtml_1) PrintCurCookies() m := regexp.MustCompile("\"showId\":\".*\",\"name\":\".*\",\"userId\"") list := m.FindStringSubmatch(toRespHtml_1) logger.Println(list) var toUrl_2 string for _, str := range list { start := len("\"showId\":\"") start_ := len("\",\"name\":\"") end := strings.Index(str, "\",\"name\":\"") end_ := strings.LastIndex(str, "\",\"userId\"") //logger.Println(start,start_,end,end_) logger.Println(str[start:end]) logger.Println(str[start_+end : end_]) toUrl_2 = fmt.Sprintf("http://pp.sohu.com/upload?folder_id=%s", str[start:end]) } //-------------------------------------------页面分割线------------------------------------------ logger.Println(toUrl_2) postDict_2 := map[string]string{} postDict_2["Upload"] = "Submit Query" postDict_2["Filename"] = "test.jpg" toRespHtml_2 := getUrlRespHtml(httpClient, toUrl_2, postDict_2, "test.jpg") logger.Println("toRespHtml=%s", toRespHtml_2) PrintCurCookies() }
get请求很简单,post请求用fidder可以截取到包,通过map[string]string构造
post upload上传复杂一点,不过也是构造fidder截取到的封包
有疑问加站长微信联系(非本文作者)