为了能够从R中访问NIST化学网络书数据库,我需要能够将一些查询传递到一个URL编码的网络地址。大多数情况下,这种转换在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")
然而,如果你尝试这个网址在您的Web浏览器http:/webbook.nist.govcgicbook.cgi?Name=Poligodial%20+%203-methoxy-4,5-methylenedioxyamphetamine%20(R,S)%20adduct,%20%23%201&Units=SI。很显然,如果你尝试查询从http:/webbook.nist.govchemistryname-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)
但这仍然不太正确,我不知道网站的所有者可以使用什么规则......。
@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"
URLencode
遵循 RFC1738规范 (见第3页第2.2节),其中规定:"只有字母数字、特殊字符"$-_.+!*'() "和用于保留目的的保留字符可以在URL中使用,不加编码。
只有字母数字、特殊字符"$-_.+!*'()",以及用于保留目的的保留字符可以在URL中不编码地使用。
也就是说,它不对复数、逗号和括号进行编码。 所以它生成的URL在理论上是正确的,但在实践中并不正确。
该 GET
中的功能 httr
斯科特提到的那个包叫做 curlEscape
从 RCurl
,它对这些标点符号进行编码。
(GET
电话 handle_url
其中调用 modify_url
其中调用 build_url
其中调用 curlEscape
.)
它生成的URL是
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
对于 curlEscape
.
这样做是你想要的吗?
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.