英文:
Issues connecting to YouTube API with Go's net/http package
问题
我认为这可能是我在SO上的第一个问题。我刚刚沉浸在Go语言中。我刚刚读完《Go语言编程入门》这本书,想写一个简单的程序来查询YT Data API v3。
问题是:当我执行go run request.go
时,我得到一个404 Not Found
错误。但是当我将传递的URL粘贴到浏览器或Postman中时,请求正常工作。这是我的func main() {}
的样子:
func main() {
// 读取API密钥
key, error_ := ioutil.ReadFile("user_data.txt")
if error_ != nil {
log.Fatal(error_)
}
api_key += string(key)
// 构建URL
url := base_url + query + api_key
// 取消下一行的注释以证明我没有疯狂。
// url = "http://ip.jsontest.com/"
// 发送请求
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
body, error_g := ioutil.ReadAll(resp.Body)
if error_g != nil {
fmt.Println(error_g)
}
fmt.Println(resp.Status)
fmt.Println(resp.Request)
fmt.Println(string(body))
defer resp.Body.Close()
// 解析响应
var vs Videos
err = json.NewDecoder(resp.Body).Decode(&vs)
if err != nil {
fmt.Printf("%T\n", err)
// fmt.Println("Error:", err)
log.Fatal(err)
}
for _, v := range vs.Items {
fmt.Println(v.Id.VideoId, v.Snippet.Title)
}
}
这是我存储库中程序的链接request.go。
英文:
I think this may be my first question on SO. I've just been immersing myself in Go. I just got done reading An Introduction to Programming in Go and I wanted to just write a simple program that would query the YT Data API v3.
The issue: when I execute go run request.go
I get a 404 Not Found
error. However when I take the URL that's passed and paste in my browser or Postman the request works fine. Here's what my func main() {}
looks like:
func main() {
// read in API key
key, error_ := ioutil.ReadFile("user_data.txt")
if error_ != nil {
log.Fatal(error_)
}
api_key += string(key)
// buil url
url := base_url + query + api_key
// Uncomment the next line to show that I'm not insane.
// url = "http://ip.jsontest.com/"
// make request
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
body, error_g := ioutil.ReadAll(resp.Body)
if error_g != nil {
fmt.Println(error_g)
}
fmt.Println(resp.Status)
fmt.Println(resp.Request)
fmt.Println(string(body))
defer resp.Body.Close()
// parse response
var vs Videos
err = json.NewDecoder(resp.Body).Decode(&vs)
if err != nil {
fmt.Printf("%T\n", err)
// fmt.Println("Error:", err)
log.Fatal(err)
}
for _, v := range vs.Items {
fmt.Println(v.Id.VideoId, v.Snippet.Title)
}
}
And here is the link to the program in my repo request.go
答案1
得分: 2
我很惊讶你的示例代码能够正常工作,假设这是完整的代码,因为你没有定义base_url
和query
来构建url := base_url + query + api_key
。我更倾向于将这部分作为注释而不是答案,但是我没有足够的声望来这样做。
我猜你可能已经尝试过这个了,但是我建议你打印出你构建的URL并仔细检查它是否类似于:
https://www.googleapis.com/youtube/v3/videos?id=7lCDEYXw3mM&key=YOUR_API_KEY
另外一个你应该考虑使用的东西是 net/url 包来构建你的URL。然后你可以这样做:
params := url.Values{}
params.Add("id", video_id)
params.Add("key", api_key)
url := &url.URL{
Host: 'https://www.googleapis.com/youtube/v3/videos',
Query: params.Encode()
}
get_url := url.String()
这样做可能会有点繁琐,但好处是它会自动处理所有的编码和查询构建工作。我猜这可能是出错的地方,假设你正确读取了你的API密钥,并且它确实对数据API有效。显然,你应该将这个逻辑封装成一个函数调用,以使其更可重用,但你明白我的意思。
英文:
I'm surprised your example works, assuming that is the whole thing, as you haven't defined base_url
or query
for url := base_url + query + api_key
. I'd rather leave that as a comment than an answer, but I don't have enough rep to do so.
I'm assuming that you've tried this, but I'd print out your built url and double check it looks something like
https://www.googleapis.com/youtube/v3/videos?id=7lCDEYXw3mM&key=YOUR_API_KEY
The other thing you should consider using, which might indirectly solve your problem, is the net/url package to build your URLs. Then you can do something like:
params := url.Values{}
params.Add("id", video_id)
params.Add("key", api_key)
url := &url.Url{
Host: 'https://www.googleapis.com/youtube/v3/videos',
Query: params.Encode()
}
get_url := url.String()
It's a bit more tedious, but the advantage here is that it takes care of all of the encoding and query building for you. My guess is that this is probably where something is going wrong, assuming you're reading in your API key properly, and it is indeed valid for the Data API. Obviously you'd want to bust that logic out into a function call to make it more reusable, but you get the idea.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论