我正在尝试使用Google API缩短数千个网址。我正在使用httr来做POST。每当我提供一个URL作为变量发布时,我得到“客户端错误:(400)错误请求”,但是当相同的URL直接作为字符串提供时(例如“http://www.google.com”),一切正常。下面提供了一个最小的例子:
library(httr)
library(httpuv)
# enter data
mydata <- data.frame(Link = "http://www.google.com")
# 1. Find OAuth settings for google:
# https://developers.google.com/accounts/docs/OAuth2InstalledApp
oauth_endpoints("google")
# 2. Register an application at https://cloud.google.com/console#/project
myapp <- oauth_app("google", key = "key goes here", secret = "secret goes here")
# 3. Get OAuth credentials
google_token <- oauth2.0_token(oauth_endpoints("google"), myapp, scope = "https://www.googleapis.com/auth/urlshortener")
返回错误:客户端错误:(400)错误请求
req <- POST('https://www.googleapis.com/urlshortener/v1/url?fields=id',
add_headers("Content-Type"="application/json"),
body='{"longUrl": mydata$Link[1]}', config(token = google_token))
stop_for_status(req)
这很好用
req <- POST('https://www.googleapis.com/urlshortener/v1/url?fields=id',
add_headers("Content-Type"="application/json"),
body='{"longUrl": "http://www.google.com"}', config(token = google_token))
stop_for_status(req)
我尝试编码网址,测试http和https,但以上都没有任何效果。任何人都可以向我提出任何建议吗?提前谢谢!
-jacek
答案 0 :(得分:1)
在我看来,mydata $ Link [1]的类是不正确的,它给出因子,但可能应该是字符。
class(mydata$Link[1])
vec<-as.character(mydata$Link[1])
答案 1 :(得分:1)
你有几个问题。
首先:数据框将字符向量强制转换为因子:
mydata <- data.frame(link = "http://www.google.com")
class(mydata$link)
#> [1] "factor"
mydata <- data.frame(link = "http://www.google.com", stringsAsFactors = FALSE)
class(mydata$link)
#> [1] "character"
其次,您将'{"longUrl": mydata$Link[1]}'
发送给谷歌 - 即
您提交的longUrl是mydata$Link[1]
,而不是
http://www.google.com
。最简单的方法是使用jsonlite
来解决这个问题
做编码:
req <- POST('https://www.googleapis.com/urlshortener/v1/url?fields=id',
body = list(longUrl = jsonlite::unbox(mydata$link[1]),
encode = "json",
config(token = google_token)
)
stop_for_status(req)
(不幸的是unbox()
是必要的,因为jsonlite默认为
将长度为1的vetors转换为js数组,而不是标量。)