R中URLencode的问题

时间:2014-02-24 01:48:12

标签: r urlencode gsub

为了能够从R访问NIST Chemistry Webbook数据库,我需要能够将一些查询传递给URL编码的Web地址。大多数情况下,此转换适用于URLencode(),但在某些情况下不适用。一例失败,例如

query="Poligodial + 3-methoxy-4,5-methylenedioxyamphetamine (R,S) adduct, # 1"

我尝试使用

获取
library(XML)
library(RCurl)
url=URLencode(paste0('http://webbook.nist.gov/cgi/cbook.cgi?Name=',query,'&Units=SI'))
doc=htmlParse(getURL(url),encoding="UTF-8")

但是,如果您在网络浏览器中尝试此网址 http://webbook.nist.gov/cgi/cbook.cgi?Name=Poligodial%20+%203-methoxy-4,5-methylenedioxyamphetamine%20(R,S)%20adduct,%20%23%201&Units=SI 它找不到名字。 显然,如果您尝试查询 http://webbook.nist.gov/chemistry/name-ser.html 它期待URL编码的字符串

"http://webbook.nist.gov/cgi/cbook.cgi?Name=Poligodial+%2B+3-methoxy-4%2C5-methylenedioxyamphetamine+%28R%2CS%29+adduct%2C+%23+1&Units=SI"

在这种情况下,是否有人知道我应该使用哪种gsub规则来达到相同类型的URL编码?还是有其他一些简单的解决方法吗?

我试过

url=gsub(" ","+",gsub(",","%2C",gsub("+","%2B",URLencode(paste('http://webbook.nist.gov/cgi/cbook.cgi?Name=',query,'&Units=SI', sep="")),fixed=T),fixed=T),fixed=T)

但这仍然不太正确,我不知道该网站的所有者可以使用哪些规则......

3 个答案:

答案 0 :(得分:3)

URLencode跟随RFC1738 specification(参见第3页第2.2节),其中指出:

  

只有字母数字,特殊字符“$ -_。+!*'(),”和   可以使用用于其保留目的的保留字符   在URL中未编码。

也就是说,它不编码加号或逗号或括号。所以它生成的URL在理论上是正确的,但在实践中却没有。

Scott提到的GET包中的httr函数从curlEscape调用了RCurl,它对这些标点符号进行了编码。

GET调用handle_url,调用modify_url,调用调用build_url的{​​{1}}。)

它生成的网址是

curlEscape

seems to work OK

paste0('http://webbook.nist.gov/cgi/cbook.cgi?Name=', curlEscape(query), '&Units=SI') ## [1] "http://webbook.nist.gov/cgi/cbook.cgi?Name=Poligodial%20%2B%203%2Dmethoxy%2D4%2C5%2Dmethylenedioxyamphetamine%20%28R%2CS%29%20adduct%2C%20%23%201&Units=SI" 具有很好的功能,您可能想要开始使用它。对代码进行最小化更改只需将httr替换为URLencode

答案 1 :(得分:1)

这样做你想要的吗?

library(httr)
url <- 'http://webbook.nist.gov/cgi/cbook.cgi'
args <- list(Name = "Poligodial + 3-methoxy-4,5-methylenedioxyamphetamine (R,S) adduct, # 1",
         Units = 'SI')
res <- GET(url, query=args)
content(res)$children$html

给予

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <meta http-equiv="Window-target" content="_top"/>

...etc.

答案 2 :(得分:1)

@Richie Cotton的解决方案也可以解决#,而URLencode()不能解决。

这是一个非常简单的示例

# Useless...
URLencode("hi$there")
[1] "hi$there"

# This is good, but only if special characters are escaped first
URLencode("hi\\$there")
[1] "hi%5C$there"

# This works without escaping!
library(httr)
curlEscape("hi$there")
[1] "hi%24there"