查找Javascript链接的Web地址

时间:2010-08-06 18:08:30

标签: javascript r

我在R中使用RCurl尝试从网站下载数据,但我无法找到要使用的网址。这是网站:

http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX

在显示的工作表上方的右上方看到如何将数据下载为.csv文件的链接?我想知道是否有办法为.csv文件找到常规HTTP地址,因为RCurl无法处理Javascript命令。

4 个答案:

答案 0 :(得分:10)

我会给你一个快速而又脏的方法来获取数据。首先,您可以使用Fiddler2 http://www.fiddler2.com/fiddler2/来检查浏览器发送的POST。这导致以下POST:

POST http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX HTTP/1.1
Host: www.invescopowershares.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Referer: http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX
Content-Type: application/x-www-form-urlencoded
Content-Length: 70669

__EVENTTARGET=ctl00%24MainPageLeft%24MainPageContent%24ExportHoldings1%24LinkButton1&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUKLTE1OTcxNjYzNw9kFgJmD2QWBAIDD2QWBAIDD2QWCAIBDw9kFgQeC2........

所以我们可以看到正在发布3个参数,即__EVENTTARGET,__ EVENTVALIDATION和__VIEWSTATE。

postForm调用所需的表单是:

postForm(ftarget, "form name" = "aspnetForm", "method" = "POST", "action" = "holdings.aspx?ticker=PGX", "id" = "aspnetForm","__EVENTTARGET"=event.target,"__EVENTVALIDATION"=event.val,"__VIEWSTATE"=view.state)

快来又脏了。我只是打开一个浏览器并获得它收到的相关参数,如下所示:

library(rcom)
ie = comCreateObject('InternetExplorer.Application')
ie[["visible"]]=T # true for debugging
ie$Navigate2("http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX")
while(comGetProperty(ie,"busy")||comGetProperty(ie,"ReadyState")<4){
Sys.sleep(1)
print(comGetProperty(ie,"ReadyState"))
}
myDoc<-comGetProperty(ie,"Document")
myPW<-comGetProperty(myDoc,"parentWindow")
comInvoke(myPW,"execScript","var dumVar1=theForm.__EVENTVALIDATION.value;var dumVar2=theForm.__VIEWSTATE.value;","JavaScript")
event.val<-myPW[["dumVar1"]]
view.state<-myPW[["dumVar2"]]
event.target<-"ctl00$MainPageLeft$MainPageContent$ExportHoldings1$LinkButton1"
ie$Quit()
ftarget<-"http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX"
web.data<-postForm(ftarget, "form name" = "aspnetForm", "method" = "POST", "action" = "holdings.aspx?ticker=PGX", "id" = "aspnetForm","__EVENTTARGET"=event.target,"__EVENTVALIDATION"=event.val,"__VIEWSTATE"=view.state)
write(web.data[1],'temp.csv')
fin.data<-read.csv('temp.csv')


> fin.data[1,]
  ticker SecurityNum                      Name CouponRate maturitydate
1    PGX   949746879 WELLS FARGO & COMPANY PFD       0.08             
     rating  Shares PercentageOfFund PositionDate
1 BBB+/Baa3 2538656       0.04442112   06/11/2012

__ EVENTVALIDATION,__ reviewSTATE可能总是相同,也可能是会话cookie。你可能可以使用RCurl来获取它们,但正如我所说,这是一个快速而肮脏的解决方案,我们只需要使用Internet Explorer。注意事项:

1)。这需要安装IE的Windows才能使用rcom位。

2)。如果您正在运行ie9,您可能需要将invescopowershares.com添加到兼容性视图设置中(因为microsoft似乎已阻止event.val&lt; -myPW [[“dumVar1”]]类型com调用)

编辑(更新)

通过更详细的网站__EVENTVALIDATION,__ CopyrightSTATE被设置为初始页面上的javascript变量。我们可以按照以下快速和肮脏的方式解析这些内容,而无需使用浏览器。

dum<-getURL("http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX")
event.target<-"ctl00$MainPageLeft$MainPageContent$ExportHoldings1$LinkButton1"
event.val<-unlist(strsplit(dum,"__EVENTVALIDATION\" value=\""))[2]
event.val<-unlist(strsplit(event.val,"\" />\r\n\r\n<script"))[1]
view.state<-unlist(strsplit(dum,"id=\"__VIEWSTATE\" value=\""))[2]
view.state<-unlist(strsplit(view.state,"\" />\r\n\r\n\r\n<script"))[1]
ftarget<-"http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX"
web.data<-postForm(ftarget, "form name" = "aspnetForm", "method" = "POST", "action" = "holdings.aspx?ticker=PGX", "id" = "aspnetForm","__EVENTTARGET"=event.target,"__EVENTVALIDATION"=event.val,"__VIEWSTATE"=view.state)
write(web.data[1],'temp.csv')
fin.data<-read.csv('temp.csv')

以上应该跨平台工作。

答案 1 :(得分:7)

点击“下载”链接执行这段JavaScript:

__doPostBack('ctl00$MainPageLeft$MainPageContent$ExportHoldings1$LinkButton1','')

__doPostBack函数似乎只是填写该页面上的几个隐藏表单字段,然后提交POST请求。

快速的Google搜索显示RCurl能够提交POST请求。因此,您需要做的是查看该页面的源代码,找到名称为“aspnetForm”的表单,从该表单中获取所有字段,并创建自己的POST请求,将字段提交到操作URL({ {3}})。

不能保证这会起作用。似乎有一个名为__VIEWSTATE的隐藏表单字段似乎对某些信息进行了编码,我不知道这是如何影响的。

答案 2 :(得分:1)

这绝对是在RCurl中获取.csv文件的方法,但是我无法弄清楚我想在getForm中使用哪些表单字段来使其工作。我应该使用附加到页面上“下载”链接的doPostBack命令中的字段,还是应该在源页面上使用aspnetForm中的字段。仅供参考,我们感兴趣的aspnetForm字段是:

” form name =“aspnetForm”method =“post”action =“holdings.aspx?ticker = PGX”id =“aspnetForm”style =“margin:0px” “

...我刚试过的postForm请求不起作用

postForm(“http://www.invescopowershares.com/products/holdings.aspx?ticker=PGX”,“form name”=“aspnetForm”,“method”=“post”,“action”=“holdings.aspx?ticker = PGX”,“id”=“aspnetForm “,”style“=”margin:0px“)

感谢您的帮助!

答案 3 :(得分:1)

qmao package现在有一个功能可以帮到你。 (它基于此问题现已删除的答案中的代码。)

您可以使用dlPowerShares 功能如下:

require("qmao")
Symbol <- "PGX"
dat <- qmao:::dlPowerShares(event.target = "ctl00$MainPageLeft$MainPageContent$ExportHoldings1$LinkButton1", 
                            action = paste0("holdings.aspx?ticker=", Symbol))
> head(dat)
  ticker SecurityNum                           Name CouponRate maturitydate    rating  Shares PercentageOfFund PositionDate
1    PGX   173080201         CITIGROUP CAPITAL XIII    0.07875   10/30/2040    BB/Ba2 2998647       0.04274939   08/31/2012
2    PGX   949746879      WELLS FARGO & COMPANY PFD    0.08000              BBB+/Baa3 2549992       0.03935854   08/31/2012
3    PGX   06739H362      BARCLAYS BK PLC              0.08125                A-/Baa3 2757635       0.03644835   08/31/2012
4    PGX   46625H621      JPMORGAN CHASE               0.08625              BBB+/Baa1 2416021       0.03310707   08/31/2012
5    PGX   060505765   BANK OF AMERICA CORP PFD 8.2    0.08200                 BB+/B1 2345508       0.03128002   08/31/2012
6    PGX   060505559 BANC OF AMERICA CORP PFD 8.625    0.08625                 BB+/B1 2259484       0.03001599   08/31/2012

在上面的代码中,event.target是javascript中的第一个字符串:__ doPostBack() 右键单击“下载”链接和“复制链接地址”时将获得的功能。

action是操作网址的产品特定部分。

在内部,代码遵循Jeff's的建议 answer并在页面源中搜索值 “aspnetForm”的字段。然后在调用postForm时使用这些值 (来自RCurl包。)

qmao package中,dlPowerShares是 由getHoldings.powershares使用。此外,getHoldings会致电getHoldings.powershares 如果传递给它的Symbols之一是PowerShares ETF的符号。


P.S。如果使用默认值调用qmao:::dlPowerShares,它将从中下载PowerShares产品列表 http://www.invescopowershares.com/products/