2014-10-08 102 views
1

我試圖使用Google API縮短數千個網址。我正在使用httr來進行POST。每當我提供一個URL作爲變量發佈時,我會得到「客戶端錯誤:(400)錯誤請求」,但是當直接以字符串形式提供相同的URL(例如「http://www.google.com」)時,一切正常。一個最小的例子提供如下:客戶端錯誤:(400)從變量提供URL時的錯誤請求

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,但以上都沒有任何效果。任何人都可以提供任何建議嗎?先謝謝你!

-jacek

回答

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數組,而不是標量。)

+0

謝謝哈德利博士!這絕對澄清事情!我加載了jsonlite包,並將其替換爲 「body = list(longUrl = jsonlite :: unbox(mydata $ link [1])}」 with 「body = list(longUrl = jsonlite :: unbox(mydata $ link [1] )),「 [用關聯的正方括號替換了關閉的大括號並添加了逗號。] jsonlite :: unbox(mydata $ Link [i])返回一個帶有長URL的標量,但是得到Error 400. req元素列出原因:badContent - 不支持的類型爲multipart/form-data的內容。我確定這與花括號有關,但似乎無法看出原因:-( – 2014-10-08 19:25:14

+0

也許您需要更新的版本httr? – hadley 2014-10-08 19:36:42

+0

非常感謝。我運行的是當前版本的httr,但是是R(3.0.1)的舊版本。更新R之後,一切正常。非常感謝你爲你所做的一切r求助! – 2014-10-08 20:00:24

1

在我看來,這個類MYDATA $鏈接[1]是不正確,它給人的因素,但也許應該是性格。

class(mydata$Link[1]) 
vec<-as.character(mydata$Link[1]) 
+0

謝謝這麼多Ruthger! – 2014-10-08 19:14:18

+0

這是我的榮幸! – 2014-10-08 21:15:08