5

我正在尝试从页面下载内容,但发现响应数据格式不正确或不完整,就好像 GET 或 getURL 在加载这些数据之前正在拉取一样。

library(httr)
library(RCurl)
url <- "https://www.vanguardcanada.ca/individual/etfs/etfs.htm"
d1 <- GET(url) # This shows a lot of {{ moustache style }} code that's not filled
d2 <- getURL(url) # This shows "" as if it didn't get anything

我不确定如何进行。我的目标是获取与浏览器中显示的链接相关的数字:

https://www.vanguardcanada.ca/individual/etfs/etfs-detail-overview.htm?portId=9548

所以在这种情况下,我想下载并抓取“9548”。

不知道为什么 getURL 和 GET 似乎得到的结果与浏览器中显示的结果大不相同。似乎数据加载缓慢,几乎就像 GET 和 getURL 在完全加载之前拉取一样。

例如,看:

x <- "https://www.vanguardcanada.ca/individual/etfs/etfs-detail-prices.htm?portId=9548"
readHTMLTable(htmlParse(GET(x)))
4

1 回答 1

9

重要的是要了解,当您抓取网页时,您将获得该页面的原始 HTML 源代码;这不一定是您将在 Web 浏览器中与之交互的内容。当您致电时,GET(url)您将获得该html/text页面的实际来源。这是直接从服务器发送的内容。现在大多数网页还假设浏览器不仅会显示 HMTL,还会在该页面上执行 javascript 代码。当大量页内内容稍后由 javascript 生成时尤其如此。这正是这个页面中发生的事情。在该页面的 html 源代码中找不到页面上的“内容”;它稍后通过 javascript 下载。

httr不会也RCurl不会执行用您实际查看的表格“填充”页面所需的 javascript。有一个名为的包RSelenium能够与浏览器交互以执行 javascript,但在这种情况下,我们实际上可以绕过它。

getURL首先,只是关于为什么不起作用的旁注。看起来这个网络服务器嗅探请求程序发送的用户代理以发送不同的内容。无论 RCurl 使用的默认用户代理是什么,都不足以从服务器获取 html。您可以通过指定不同的用户代理来解决此问题。例如

d2 <- getURL(url, .opts=list(useragent="Mozila 5.0"))

似乎工作。

但回到主要问题。在处理此类问题时,我强烈建议您使用 Chrome 开发人员工具(或您喜欢的浏览器中的任何等效工具)。在 Chrome 开发者工具中,特别是在网络选项卡上,您可以看到 Chrome 为获取数据而发出的所有请求

在此处输入图像描述

如果您单击第一个(“etfs.html”),您可以看到该请求的标题和响应。GET在响应子选项卡上,您应该看到与或找到的内容完全相同getURL。然后我们下载一堆 CSS 和 javascript 文件。看起来最有趣的文件是“GetETFJson.js”。这实际上似乎以几乎类似于 JSON 的格式保存大部分数据。它实际上在 JSON 块前面有一些真正的 javascript,这会妨碍它。但我们可以下载该文件

d3 <- GET("https://www.vanguardcanada.ca/individual/mvc/GetETFJson.js")

并将内容提取为文本

p3 <- content(d3, as="text")

然后把它变成一个R对象

library(jsonlite)
r3 <- fromJSON(substr(p3,13,nchar(p3)))

同样,我们在substr开始时使用上面的方法去除非 JSON 的内容,以便更容易解析。

现在,您可以探索返回的对象。但看起来您想要的数据存储在以下向量中

cbind(r3$fundData$Fund$profile$portId, r3$fundData$Fund$profile$benchMark)

      [,1]   [,2]                                                                            
 [1,] "9548" "FTSE All World ex Canada Index in CAD"                                         
 [2,] "9561" "FTSE Canada All Cap Index in CAD"                                              
 [3,] "9554" "Spliced Canada Index"                                                          
 [4,] "9559" "FTSE Canada All Cap Real Estate Capped 25% Index"                              
 [5,] "9560" "FTSE Canada High Dividend Yield Index"                                         
 [6,] "9550" "FTSE Developed Asia Pacific Index in CAD"                                      
 [7,] "9549" "FTSE Developed Europe Index in CAD"                                            
 [8,] "9558" "FTSE Developed ex North America Index in CAD"                                  
 [9,] "9555" "Spliced FTSE Developed ex North America Index Hedged in CAD"                   
[10,] "9556" "Spliced Emerging Markets Index in CAD"                                         
[11,] "9563" "S&P 500 Index in CAD"                                                          
[12,] "9562" "S&P 500 Index in CAD Hedged"                                                   
[13,] "9566" "NASDAQ US Dividend Achievers Select Index in CAD"                              
[14,] "9564" "NASDAQ US Dividend Achievers Select Index Hedged in CAD"                       
[15,] "9557" "CRSP US Total Market Index in CAD"                                             
[16,] "9551" "Spliced US Total Market Index Hedged in CAD"                                   
[17,] "9552" "Barclays Global Aggregate CAD Float Adjusted Index in CAD"                     
[18,] "9553" "Barclays Global Aggregate CAD 1-5 Year Govt/Credit Float Adj Ix in CAD"        
[19,] "9565" "Barclays Global Aggregate Canadian 1-5 Year Credit Float Adjusted Index in CAD"
[20,] "9568" "Barclays Global Aggregate ex-USD Float Adjusted RIC Capped Index Hedged in CAD"
[21,] "9567" "Barclays U.S. Aggregate Float Adjusted Index Hedged in CAD"  

因此,希望这足以提取您需要使用更多数据识别 URL 路径的数据。

于 2014-08-07T03:49:20.907 回答