1

我正在尝试使用 Google API 缩短数千个 URL。我正在使用 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)

我尝试对 URL 进行编码,同时测试了 http 和 https,但以上似乎都没有任何效果。谁能给我任何建议?先感谢您!

-雅切克

4

2 回答 2

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]}'给 google - 即您提交的 longUrl 是mydata$Link[1],而不是 http://www.google.com。最简单的方法是使用jsonliteto 进行编码来解决这个问题:

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 的向量转换为 js 数组,而不是标量。)

于 2014-10-08T17:34:27.553 回答
1

在我看来 mydata$Link[1] 的类不正确,它给出了因素但可能应该是字符。

class(mydata$Link[1])
vec<-as.character(mydata$Link[1])
于 2014-10-08T07:55:59.227 回答