gpt4 book ai didi

api - 从Twitter客户端读取响应返回错误

转载 作者:行者123 更新时间:2023-12-01 22:11:34 25 4
gpt4 key购买 nike

我正在尝试制作一个调用twitter搜索API的函数(使用dghubble/go-twitter)
但是,当我尝试从该API读取响应时,我得到了http2: response body closed这是我的代码:

func SearchTweets(query string) string {
config := oauth1.NewConfig("consumer_key", "consumer_secret")
token := oauth1.NewToken("access_token", "token_secret")
httpClient := config.Client(oauth1.NoContext, token)

// Twitter client
client := twitter.NewClient(httpClient)

// Search Tweets
_ , resp, err := client.Search.Tweets(&twitter.SearchTweetParams{
Query: "elon",
Count: 50,
})


if err != nil {
return err.Error()
}

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err.Error()
}
return string(body)
}

最佳答案

此答复中引用的行号和文件是在回答之日记录的,因此不能保证它们永远正确无误。
dghubble's go-twitter search.go的第62行中,您正在调用的client.Search.Tweets()函数:

resp, err := s.sling.New().Get("tweets.json").QueryStruct(params).Receive(search, apiError)
请注意,它使用 sling包构造和发送http请求,以及接收和解析http(JSON)响应。它所引用的 sling包可以在 here中找到。
具体来说,请密切注意 sling.go。在第366行上,有一条注释指出:“接收是调用请求和执行的简写。”
Request()行上找到的 280函数仅根据 *http.Request对象的属性构造一个 Sling。它返回所述请求以及错误(签名为 func (s *Sling) Request() (*http.Request, error)) Do()函数是关键部分。它执行作为第一个参数传递的http请求,尝试将(JSON)响应解析为提供的第二个参数(一个interface {},它应指向您希望将响应解析为的对象),并同时尝试解析提供给第三个参数的任何错误。毕竟,它 关闭了响应主体。 具体来说,注意第385和386行:
// when err is nil, resp contains a non-nil resp.Body which must be closed
defer resp.Body.Close()
换句话说,响应主体在它进入go-twitter Tweets()范围之前就已关闭,因此您肯定无法最终读取该主体。毕竟,这些库的要点是为您省去了读取和解析响应正文等内容的麻烦。
通常,您应该能够使用提供的软件包获得所需的信息。具体来说, Tweets()函数具有以下签名: func (s *SearchService) Tweets(params *SearchTweetParams) (*Search, *http.Response, error)。请注意,第一个返回值的类型为 *Search。这是从 Receive()以及 Do()函数读取的对象。它应该在关闭之前保存 *http.Response主体中的所有信息:
search , resp, err := client.Search.Tweets(&twitter.SearchTweetParams{
Query: "elon",
Count: 50,
})
search对象的类型为 *Search,其定义可以在 here中找到。它包括状态的一部分( Tweet结构)以及一些元数据。您还可能会发现 here,这对 Tweet结构的定义很有帮助。
最后,如果出于某种原因您确实需要自己处理请求主体,则必须从头开始执行请求,这无论如何都会破坏 go-twittersling库的目的。您可以在 sling的基础上构建一些请求,但它不是很漂亮(实际上,从头开始构建请求也可能更干净)。不过,这是一个(未经测试的)示例,它是通过引用本文前面提到的链接以及 this one编写的代码:
func MyTweetsFunc(httpClient *http.Client, requestBuilder *sling.Sling, params *twitter.SearchTweetParams) 
{
// Use sling's Request() to construct the request, just as Receive() does
req, err := requestBuilder.New().Get("tweets.json").QueryStruct(params).Request()
if err != nil {
// handle the error
}

// Get the response through the httpClient, since a sling client would parse and close the body automatically.
resp, err := httpClient.Do(req)

if err != nil {
// handle the error
}

// Now you can do whatever you want with resp, which is simply an *http.Response. Its body is open for reading.
}
requestBuilder可以这样构造:
const twitterAPI = "https://api.twitter.com/1.1/"

requestBuilder := sling.New().Client(httpClient).Base(twitterAPI)
您通常将 httpClient传递给 twitter.NewClient()的客户端

关于api - 从Twitter客户端读取响应返回错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63267744/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com