• 【Go学习】go 原生库net/http发送 GET POST 请求


    go基础语法,一直没怎么练习,语法这东西不用就忘,工作中多多少少还接触到爬虫,索性强制用go来写,写爬虫不是目的,目的是为了练习go语法,强化记忆。
    毕竟go处理一些字符串和Python比,我认为还是十分繁琐的,而且爬虫瓶颈是限于网络和目标地址响应,所以在写爬虫性能上,go不一定胜过Python。

    已有的轮子

    目前已经有了很多他人封装好的请求库,但是还是要懂原生库的用法,以下是我在github上找的封装请求库star数量1k+的(以下排名不分先后):

    注意以下示例皆要以编写测试程序的方式书写,文件名以_test.go后缀结尾。

    GET请求

    github地址

    package http_demo
    
    import (
    	"encoding/json"
    	"errors"
    	"fmt"
    	"io/ioutil"
    	"net/http"
    	"testing"
    )
    
    func Requests(url string) (content string, err error) {
    	// 创建 http 客户端
    	client := &http.Client{}
    
    	// 创建请求
    	req, _ := http.NewRequest("GET", url, nil)
    
    	// GET 请求携带查询参数
    	q := req.URL.Query()
    	q.Add("auth_key", "sky_kk")
    	q.Add("another_thing", "foo & bar")
    	req.URL.RawQuery = q.Encode()
    
    	//req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36")
    	// 设置请求头
    	req.Header.Set("User-Agent", "test")
    
    	// 发送请求
    	resp, err := client.Do(req)
    
    	if err != nil {
    		// 格式化返回错误
    		return "", errors.New(fmt.Sprintf("请求出错 %s", err))
    	}
    
    	// 最后关闭连接
    	defer resp.Body.Close()
    
    	// 读取内容
    	body, err := ioutil.ReadAll(resp.Body)
    	if err != nil {
    		return "", errors.New(fmt.Sprintf("解析内容出错 %s", err))
    	}
    	//fmt.Println(string(body))
    	return string(body), nil
    }
    
    func TestReqUrl(t *testing.T) {
    	url := "https://httpbin.org/get"
    	content, err := Requests(url)
    	if err != nil {
    		fmt.Println("请求错误", err)
    		return
    	}
    	t.Log(fmt.Sprintf("结果 
     %s", content))
    }
    

    POST 请求

    POST 请求携带参数的方式,根据Content-Type不同 有多种请求方式

    POST from请求

    github地址

    package http_demo
    
    import (
    	"errors"
    	"fmt"
    	"io/ioutil"
    	"net/http"
    	"net/url"
    	"testing"
    )
    
    func PostReq(targetUrl string) (content string, err error) {
    	// 最简单的发送 post请求 携带 form参数
    	resp, err := http.PostForm(targetUrl, url.Values{"username": {"wxy"}, "password": {"wxy666"}})
    
    	// 相当于这种
    	//req.Header.Set("Content-Type", "multipart/form-data")
    
    	if err != nil {
    		return "", errors.New(fmt.Sprintf("请求错误 %s", err))
    	}
    	fmt.Println(fmt.Sprintf("响应状态 %s", resp.Status))
    
    	// 记得关闭客户端
    	defer resp.Body.Close()
    	// 读取内容
    	body, err := ioutil.ReadAll(resp.Body)
    	if err != nil {
    		return "", errors.New(fmt.Sprintf("读取内容错误 %s", err))
    	}
    	content = string(body)
    	return content, nil
    
    }
    
    func TestReq3(t *testing.T) {
    	targetUrl := "https://httpbin.org/post"
    
    	content, err := PostReq(targetUrl)
    	if err != nil {
    		fmt.Println("请求错误", err)
    		return
    	}
    	fmt.Println(content)
    }
    

    POST JSON 方式请求

    github地址

    package http_demo
    
    import (
    	"bytes"
    	"errors"
    	"fmt"
    	"io/ioutil"
    	"net/http"
    	"net/url"
    	"strings"
    	"testing"
    )
    
    // post form请求 务必设置  Content-Type
    func ReqPostForm(targetUrl string) (content string, err error) {
    	// 创建 http 客户端
    	client := &http.Client{}
    
    	form := url.Values{}
    	form.Add("ln", "ln222")
    	form.Add("ip", "1.1.1.1")
    	form.Add("ua", "ua123")
    
    	// 创建请求
    	req, _ := http.NewRequest("POST", targetUrl, strings.NewReader(form.Encode()))
    
    	req.Header.Set("User-Agent", "test")
    	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    
    	// 发送请求
    	resp, err := client.Do(req)
    
    	if err != nil {
    		// 格式化返回错误
    		return "", errors.New(fmt.Sprintf("请求出错 %s", err))
    	}
    
    	// 最后关闭连接
    	defer resp.Body.Close()
    
    	// 读取内容
    	body, err := ioutil.ReadAll(resp.Body)
    	if err != nil {
    		return "", errors.New(fmt.Sprintf("解析内容出错 %s", err))
    	}
    	return string(body), nil
    }
    
    // post json方式请求
    func ReqPostJson(targetUrl string) (content string, err error) {
    
    	var jsonStr = []byte(`{"title":"this is a title", "cate": 1}`)
    
    	req, _ := http.NewRequest("POST", targetUrl, bytes.NewBuffer(jsonStr))
    
    	req.Header.Set("X-Custom-Header", "myvalue")
    	req.Header.Set("Content-Type", "application/json")
    
    	client := &http.Client{}
    
    	resp, err := client.Do(req)
    
    	if err != nil {
    		return "", errors.New(fmt.Sprintf("请求出错 %s", err))
    	}
    	defer resp.Body.Close()
    
    	body, _ := ioutil.ReadAll(resp.Body)
    
    	return string(body), nil
    
    }
    
    func TestReqPost(t *testing.T) {
    	targetUrl := "https://httpbin.org/post"
    
    	c1, _ := ReqPostForm(targetUrl)
    	t.Log(fmt.Sprintf("
    from表单返回: 
     %s", c1))
    
    	c2, _ := ReqPostJson(targetUrl)
    	t.Log(fmt.Sprintf("
    Json请求返回: 
     %s", c2))
    
    }
    
  • 相关阅读:
    php socket 客户端代码
    linux crontab定时执行
    加载 pcntl 多进程
    Xdebug 配置
    Zend Debugger 配置
    windows SVN搭建
    深度学习笔记:优化方法总结(BGD,SGD,Momentum,AdaGrad,RMSProp,Adam)
    操作系统-分段机制
    C++中的new、operator new与placement new
    线程安全的概念
  • 原文地址:https://www.cnblogs.com/CharmCode/p/14198657.html
Copyright © 2020-2023  润新知