2017-07-07 61 views
0

我试图在Web上刮一个公共数据提供者,但当我点击一个按钮传递一个参数给JS时,我被卡住了。这里是我的尝试:如何使用数据参数链接使用rvest

require(rvest) 
url <- 'https://myterna.terna.it/SunSet/Public/' 
page <- url %>% read_html() 
node_link <- page %>% html_node('.sub-item:nth-child(1) .postlink') 

node_link我可以很容易地找到目标网页,因为这HTML标签的href

<a href="/SunSet/Public/Pubblicazioni" 
    class="postlink" 
    data-params="filter.IdSezione=52767620567B3077E053A8829B0A9478"> 

的一点是,我不能轻松地检索链接的页面,因为内容还有其他按钮指向相同链接。各个按钮之间的唯一区别是data-params属性,它可能必须提供给JS以检索特定内容。

关于如何解决该问题的任何想法?

回答

1

强制性抬头:

这不是真的清楚,如果网站允许刮削,该Legal Notice授权是授予本网站供个人使用,不得用于商业目的的出版专门的文件复制,提供源的名称已正确指示。

尊重他们的服务条款。

点击该链接检查网络活动,我们可以看到该网页发出POST请求https://myterna.terna.it/SunSet/Public/Pubblicazioni/List。我们可以找到请求的headersparams发送。

par <- '{"draw":1,"columns":[{"data":0,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":1,"name":"","searchable":true,"orderable":true,"search":{"value":"","regex":false}},{"data":2,"name":"","searchable":false,"orderable":false,"search":{"value":"","regex":false}},{"data":3,"name":"","searchable":false,"orderable":false,"search":{"value":"","regex":false}},{"data":4,"name":"","searchable":false,"orderable":false,"search":{"value":"","regex":false}},{"data":5,"name":"","searchable":false,"orderable":false,"search":{"value":"","regex":false}},{"data":6,"name":"","searchable":false,"orderable":false,"search":{"value":"","regex":false}},{"data":7,"name":"","searchable":false,"orderable":false,"search":{"value":"","regex":false}}],"order":[],"start":0,"length":10,"search":{"value":"","regex":false},"filter":{"IdSezione":"52767620567B3077E053A8829B0A9478","Titolo":"","Id":"","ExtKey":"","TipoPubblicazione":"","SheetName":"","Anno":"2017","Mese":"7","Giorno":"","DataPubblicazione":"","TipoDatoPubblicazione":""},"details":{}}' 

这是json,我们可以分析,如果我们想改变自己的价值观(虽然我尝试了几种不同的过滤器和它确实没有回应太多)

par <- jsonlite::fromJSON(par) 
par$filter$Mese <- '7' 

至于头只X-Requested-With:MLHttpRequest是真的所以我们可以把它降低到这个水平。

response <- POST('https://myterna.terna.it/SunSet/Public/Pubblicazioni/List', 
    add_headers('X-Requested-With' = 'XMLHttpRequest'), 
    body = par, 
    encode = 'json') 

json_data <- content(response)$data 

这将返回一个列表,我们可以放心地进行改造,以数据帧,方便使用:

df <- data.frame(matrix(unlist(json_data), nrow=length(json_data), byrow=TRUE)) 

head(df, 2) 
#>                  X1 
#> 1  SbilanciamentoAggregatoZonale_SegnoGiornaliero_Orario_20170709 
#> 2 SbilanciamentoAggregatoZonale_SegnoGiornaliero_QuartoOrario_20170709 
#>      X2 
#> 1 /Date(1499680800000)/ 
#> 2 /Date(1499680800000)/ 
#>                       X3 
#> 1 <div class="actions detail-inline export" data-pk="53F4A57FCB70304EE0532A889B0A7758"></div> 
#> 2 <div class="actions detail-inline export" data-pk="53F4A57FCB6D304EE0532A889B0A7758"></div> 
#>         X4 X5        X6 
#> 1 53F4A57FCB70304EE0532A889B0A7758 25  SEGNO_MACROZONALE_ORARIO 
#> 2 53F4A57FCB6D304EE0532A889B0A7758 25 SEGNO_MACROZONALE_QUARTO_ORARIO 
#>     X7   X8 
#> 1 Segno Giornaliero  Orario 
#> 2 Segno Giornaliero Quarto Orario 
+0

谢谢@GGamba,你得到了点!我认为网络上的这个主题没有太多,所以你的贡献绝对有用! –

1

好的,基本上我错过了HTTP工作机制。经过几天的研究,我明白正确的做法是使用httr包的方式显示如下。

所有我取回从公共网页所需的所有设置的第一:

lnkd_url <- paste0(dirname(dirname(url)), 
        node_link %>% 
         html_attr('href')) 
lnkd_id <- strsplit(zs_node %>% 
         html_attr('data-params'), '=')[[1]][2] 

然后就可以启动POST请求到目标页面:

lnkd_page <- POST(lnkd_url, 
        body = list('filter.IdSezione' = lnkd_id) 

这就是它!