为了能够从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)
但这仍然不太正确,我不知道该网站的所有者可以使用哪些规则......
答案 0 :(得分:3)
URLencode
跟随RFC1738 specification(参见第3页第2.2节),其中指出:
只有字母数字,特殊字符“$ -_。+!*'(),”和 可以使用用于其保留目的的保留字符 在URL中未编码。
也就是说,它不编码加号或逗号或括号。所以它生成的URL在理论上是正确的,但在实践中却没有。
Scott提到的GET
包中的httr
函数从curlEscape
调用了RCurl
,它对这些标点符号进行了编码。
(GET
调用handle_url
,调用modify_url
,调用调用build_url
的{{1}}。)
它生成的网址是
curlEscape
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"