当前位置: 代码网 > it编程>前端脚本>Golang > Go标准库之Requests的介绍与基本使用

Go标准库之Requests的介绍与基本使用

2024年05月26日 Golang 我要评论
一、介绍官方文档 doc:https://pkg.go.dev/github.com/levigross/grequestsgithub:http://github.com/levigross/gre

一、介绍

官方文档 doc: https://pkg.go.dev/github.com/levigross/grequests

github: http://github.com/levigross/grequests

python中的requests库非常强大,所以go开发者模仿python的requests库,由此诞生了grequests库。grequests提供了一系列便利功能,使得发送http请求变得简单高效。下面就是grequests在golang中实现的一些关键特性:

  • 响应序列化grequests支持将http响应内容序列化为json和xml格式,让处理api响应时更为方便。
  • 文件上传和下载:提供了便捷的方式来上传和下载文件,无需复杂的配置。
  • http动词支持:支持广泛的http动词,包括get、head、post、put、delete、patch以及options,可以覆盖大多数http请求场景。

二、安装

要开始使用grequests库,你需要先在你的go环境中安装它。通过下面的命令即可完成安装:

go get -u github.com/levigross/grequests

三、导入

在安装完grequests后,你可以通过import语句把它引入到你的go代码中:

import "github.com/levigross/grequests"

四、基本使用

4.1 发送get 请求

下面是一个发送get请求的示例,其中演示了如何获取http响应并打印出来:

func get() {
	resp, err := grequests.get("http://127.0.0.1:8080/book/", nil)
	if err != nil {
		log.fatalln("unable to make request: ", err)
	}

	if !resp.ok {
		log.fatalln("请求超时!")
	}

	// 解析响应的json数据
	var data []map[string]interface{}
	if err := resp.json(&data); err != nil {
		log.fatalln("unable to parse json response: ", err)
	}
	fmt.println(data)
}

上面的代码首先使用get方法发送get请求,然后检查是否有错误发生。如果没有错误,就可以通过resp.json()方法获取响应的文本内容。

4.2 post请求发送json数据

在下面的例子中,我们创建了一个map对象来保存我们想要发送的json数据。然后我们通过roption创建了一个请求选项对象,并在其中指定了json为发送的数据类型。最后,我们调用post方法来发送请求:

func post() {
	postdata := map[string]string{
		"id":   "1",
		"name": "go入门到进阶",
	}
	geq := &grequests.requestoptions{
		json: postdata,
	}
	resp, err := grequests.post("http://127.0.0.1:8080/book/create", geq)
	if err != nil {
		log.fatalln("unable to make request: ", err)
	}
	fmt.println(resp.string())
}

下面是代码的逐行解释:

postdata := map[string]string{"id": "1", "name": "go入门到进阶"}

这里定义了一个map[string]string类型的变量postdata,其中包含了两个键值对,分别是"id"和"name",它们的值分别是"1"和"go入门到进阶"。

geq := &grequests.requestoptions{json: postdata}

这里创建了一个grequests.requestoptions类型的变量geqgrequests.requestoptions是一个结构体,用于配置http请求的各种选项,如url、方法、头信息、数据等。在这个例子中,我们通过json字段将postdata作为json数据传递给post请求。

resp, err := grequests.post("http://127.0.0.1:8080/book/create", geq)

这里调用grequests.post函数发起一个post请求。http://127.0.0.1:8080/book/create是请求的目标url,而geq是请求的配置选项。grequests.post函数会返回一个response对象和一个可能的错误。

if err != nil { log.fatalln("unable to make request: ", err) }

如果grequests.post函数调用时发生错误,这个条件块会执行。log.fatalln函数会打印错误消息并退出程序。

fmt.println(resp.string())

如果请求成功,这个条件块会执行。resp.string()方法会返回响应体的字符串表示,然后使用fmt.println函数将其打印到标准输出。

总的来说,这段代码的作用是向本地服务器(假设在127.0.0.1:8080上)的/book/create路径发送一个post请求,请求体是json格式的数据,包含一个id和书名。如果请求成功,它会打印出服务器的响应。如果请求失败,它会打印出错误信息并退出程序。

4.3 post 文件上传

文件上传同样简单。你可以通过requestoptions指定文件:

func uploadfile() {
	// 允许您通过指定磁盘上的位置来创建fileupload结构片
	// 打开要上传的文件
	file, err := os.open("./go.mod")
	if err != nil {
		log.fatalln("unable to open file: ", err)
	}
	defer file.close()

	// 创建fileupload结构片
	ro := &grequests.requestoptions{
		files: []grequests.fileupload{{
			filename:     "1.txt", // 上传后的文件名称
			fieldname:    "file",  // 上传文件对应字段
			filecontents: file, // 使用文件内容作为filecontents
		}},
	}
	// 发送post请求
	resp, err := grequests.post("http://127.0.0.1:8080/book/upload/", ro)
	if err != nil {
		log.fatalln("unable to make request: ", err)
	}
	fmt.println(resp.string())
}

在上述代码中,我们创建了一个fileupload结构,通过filenamefieldnamefilecontents来指定我们要上传的文件详情。

4.4 gorequests 使用代理

gorequest代理,下面是一个简单的例子,需要把proxies中的url添加为*url.url代理:

func proxy() {
	// 代理服务器
	const proxyserver = "http-pro.xxx.com:9010"

	// 代理隧道验证信息
	const proxyuser = "xxxxxxxxx"
	const proxypass = "xxxxxxxxx"

	// 初始化代理url
	proxyurl, _ := url.parse("http://" + proxyuser + ":" + proxypass + "@" + proxyserver)

	// 创建请求选项
	ro := &grequests.requestoptions{
		proxies: map[string]*url.url{
			"http": proxyurl,
		},
		headers: map[string]string{
			"user-agent": "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/105.0.0.0 safari/537.36",
		},
	}

	// 发起get请求
	resp, err := grequests.get("http://www.example.com", ro)
	if err != nil {
		fmt.println("error:", err)
		return
	}

	// 打印响应状态码
	fmt.println("status code:", resp.statuscode)

	// 打印响应体
	fmt.println("response:", resp.string())
}

下面是代码的逐行解释:

// 代理服务器

这一行是一个注释,声明了接下来的代码将定义代理服务器的url。

const proxyserver = "http-pro.xxx.com:9010"

这里定义了一个常量proxyserver,它的值是代理服务器的url,格式为http://host:port

// 代理隧道验证信息

这一行是一个注释,声明了接下来的代码将定义代理隧道的验证信息。

const proxyuser = "xxxxxxxxx"

这里定义了一个常量proxyuser,它的值是代理隧道的用户名。

const proxypass = "xxxxxxxxx"

这里定义了一个常量proxypass,它的值是代理隧道的密码。

// 初始化代理url

这一行是一个注释,说明接下来的代码将创建代理url。

proxyurl, _ := url.parse("http://" + proxyuser + ":" + proxypass + "@" + proxyserver)

这行代码使用url.parse函数创建了一个代理url。它将代理隧道的用户名、密码和代理服务器地址组合成一个url,格式为http://username:password@host:port_是忽略返回值的约定,因为返回值通常不需要使用。

// 创建请求选项

这一行是一个注释,说明接下来的代码将创建一个grequests.requestoptions结构体,用于配置http请求。

ro := &grequests.requestoptions{

这里开始定义grequests.requestoptions结构体变量ro

proxies: map[string]*url.url{

这里定义了proxies字段,它是一个映射,将协议(如"http")映射到代理url。

"http": proxyurl,

这行代码将代理url设置为http协议的代理。

},

这是映射定义的结束。

headers: map[string]string{

这里定义了headers字段,它是一个映射,将http头字段(如"user-agent")映射到相应的值。

"user-agent": "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/105.0.0.0 safari/537.36",

这行代码设置了一个http头字段,即用户代理(user-agent),用于标识发起请求的客户端。

},

这是映射定义的结束。

}

这是grequests.requestoptions结构体变量的定义结束。

// 发起get请求

这一行是一个注释,说明接下来的代码将发起一个get请求。

resp, err := grequests.get("http://www.example.com", ro)

这行代码使用grequests.get函数发起一个get请求。http://www.example.com是请求的目标url,而ro是请求的配置选项。grequests.get函数会返回一个response对象和一个可能的错误。

if err != nil {

如果grequests.get函数调用时发生错误,这个条件块会执行。

fmt.println("error:", err)

这行代码打印出错误信息。

return

这行代码表示如果发生错误,函数将返回,不继续执行。

}

这是错误处理块的结束。

fmt.println("status code:", resp.statuscode)

如果请求成功,这行代码会打印出响应的状态码。

fmt.println("response:", resp.string())

4.5 gorequests 使用session

下面是使用session的一个例子:

session := grequests.session{
		requestoptions: &grequests.requestoptions{
			headers: map[string]string{
				"authority":  "mp3.haoge500.com",
				"referer":    "https://www.zz123.com/",
				"user-agent": "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/107.0.0.0 safari/537.36",
			},
		},
	}

五、http服务端代码

package main

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"net/http"
	"os"
)

type book struct {
	id   string `json:"id"`
	name string `json:"name"`
}

type bookhandler struct {
}

func (b *bookhandler) registerroutes(server *gin.engine) {
	bg := server.group("/book")
	bg.post("/upload", b.upload)
	bg.post("/create", b.create)
	bg.get("/", b.getallbooks) // 查询书籍
}

func (b *bookhandler) upload(ctx *gin.context) {
	// 从请求中获取文件
	file, err := ctx.formfile("file")
	if err != nil {
		ctx.json(http.statusbadrequest, gin.h{"error": "无法获取上传的文件"})
		return
	}

	// 将文件保存到服务器
	// 注意:这里需要确保保存文件的目录存在,并且服务器有写入权限
	savepath := "./uploads/" + file.filename
	if err := ctx.saveuploadedfile(file, savepath); err != nil {
		ctx.json(http.statusinternalservererror, gin.h{"error": "文件保存失败"})
		return
	}

	ctx.json(http.statusok, gin.h{"message": "文件上传成功"})
}

func (b *bookhandler) create(ctx *gin.context) {
	var req book
	if err := ctx.bind(&req); err != nil {
		return
	}

	// 将新的书籍数据保存到data.json文件中
	if err := addbooktofile(&req); err != nil {
		ctx.json(http.statusinternalservererror, gin.h{"error": "failed to save book data"})
		return
	}

	ctx.json(http.statusok, gin.h{"message": "book added successfully"})
}
func (b *bookhandler) getallbooks(c *gin.context) {
	// 从data.json文件中读取书籍数据
	books, err := getbooksfromfile()
	if err != nil {
		c.json(http.statusinternalservererror, gin.h{"error": "failed to read book data"})
		return
	}

	// 获取url查询参数中的id
	id := c.query("id")

	// 如果提供了id,查找具有匹配id的书籍列表
	if id != "" {
		// 查找具有匹配id的书籍
		var foundbooks []book
		for _, book := range books {
			if book.id == id {
				foundbooks = append(foundbooks, book)
			}
		}
		// 如果找到了匹配的书籍,返回这些书籍
		if len(foundbooks) > 0 {
			c.json(http.statusok, foundbooks)
			return
		}
		// 如果没有找到匹配的书籍,返回404
		c.json(http.statusnotfound, gin.h{"error": "books not found"})
		return
	}

	// 如果没有提供id,返回所有书籍
	c.json(http.statusok, books)
}
func addbooktofile(book *book) error {
	// 读取现有的data.json文件内容
	var books []book
	data, err := os.readfile("data.json")
	if err != nil && !os.isnotexist(err) {
		return err
	}

	// 如果文件存在,解析现有的书籍数据
	if err == nil {
		if err := json.unmarshal(data, &books); err != nil {
			return err
		}
	}

	// 将新的书籍添加到数组中
	books = append(books, *book)

	// 将更新后的书籍数组序列化为json
	newdata, err := json.marshalindent(books, "", "    ")
	if err != nil {
		return err
	}

	// 将序列化的json数据写入data.json文件
	if err := os.writefile("data.json", newdata, 0644); err != nil {
		return err
	}

	return nil
}
func getbooksfromfile() ([]book, error) {
	// 读取data.json文件内容
	data, err := os.readfile("data.json")
	if err != nil {
		return nil, err
	}

	// 解析json数据到书籍数组中
	var books []book
	if err := json.unmarshal(data, &books); err != nil {
		return nil, err
	}

	return books, nil
}

func initwebserver(bookhandler *bookhandler) *gin.engine {
	server := gin.default()
	bookhandler.registerroutes(server)
	return server
}

func main() {
	// 确保上传目录存在
	os.mkdirall("./uploads", 0755)

	bookhandler := &bookhandler{}
	server := initwebserver(bookhandler)
	server.run(":8080") // 在8080端口启动服务器
}

以上就是go标准库之requests的介绍与基本使用的详细内容,更多关于go requests的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com