【问题标题】:Client error: (400) Bad Request when URL provided from a variable客户端错误:(400)从变量提供 URL 时出现错误请求
【发布时间】:2014-10-09 03:36:54
【问题描述】:

我正在尝试使用 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,但上述方法似乎都没有任何效果。谁能给我任何建议?提前谢谢!

-杰克

【问题讨论】:

    标签: r google-api httr google-url-shortener


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

    【讨论】:

    • 谢谢哈德利博士!这绝对澄清了事情!我加载了jsonlite包并将“body = list(longUrl = jsonlite::unbox(mydata$link[1])}”替换为“body = list(longUrl = jsonlite::unbox(mydata$link[1])), " [用匹配的正则括号替换右大括号并添加逗号。] jsonlite::unbox(mydata$Link[i]) 返回带有长 URL 的标量,但我收到错误 400。req 元素列出了原因:badContent -类型不受支持的内容:multipart/form-data。我很确定这与大括号有关,但似乎不明白为什么:-(
    • 也许您需要更新版本的 httr?
    • 非常感谢。我正在运行当前版本的 httr,但运行的是旧版本的 R (3.0.1)。更新 R 后一切正常。非常感谢您的帮助!
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2019-11-10
      • 2020-05-20
      • 2021-04-30
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      • 2015-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多