最近都在学习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截取到的封包