2017-07-07 1 views
0

Ich versuche, Web-Scrape einen öffentlichen Datenanbieter, aber ich blieb stecken, wenn ich auf eine Schaltfläche klicken musste, übergeben Sie einen Parameter an die JS. Hier ist mein Versuch:Wie folgt man einem Link mit Datenparametern mit 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') 

In node_link Ich kann leicht die Zielseite als href dieses HTML-Tag finden:

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

Der Punkt ist, dass ich nicht einfach den Inhalt der verlinkten Seite abgerufen werden können, weil Es gibt andere Tasten, die auf den gleichen Link zeigen. Der einzige Unterschied zwischen den verschiedenen Knöpfen ist das data-params Attribut, das wahrscheinlich dem JS gegeben werden muss, um den spezifischen Inhalt zu erhalten.

Haben Sie Ideen, wie Sie das Problem lösen können?

Antwort

1

Obligatorische Heads-up:

Es ist nicht wirklich klar, ob die Website Schaben ermöglichen, die Legal Notice sagt Genehmigung für die Vervielfältigung von Dokumenten auf dieser Website ausschließlich für den persönlichen Gebrauch veröffentlicht gewährt wird und nicht für kommerzielle Zwecke, vorausgesetzt, Der Name der Quelle wird richtig angezeigt.

Verwenden Sie dies unter Berücksichtigung ihrer Nutzungsbedingungen.

Wenn Sie die Netzwerkaktivität überprüfen, wenn Sie auf diesen Link klicken, können wir sehen, dass die Webseite eine POST Anfrage an https://myterna.terna.it/SunSet/Public/Pubblicazioni/List sendet. Wir können sowohl die angeforderten headers als auch die params senden.

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":{}}' 

Dies ist json, können wir ihre Werte analysieren und ändern, wenn wir wollen (obwohl ich ein paar verschiedene Filter ausprobiert und es funktioniert nicht reagieren viel)

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

Was Header nur X-Requested-With:MLHttpRequest wirklich ist benötigt, damit wir es darauf reduzieren können.

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 

Diese Liste gibt, dass wir sicher auf einen Datenrahmen für die bequeme Nutzung verwandeln können:

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

Danke @GGamba, haben Sie den Punkt! Ich denke, es gibt nicht so viel zu diesem Thema im Internet, also ist Ihr Beitrag definitiv nützlich! –

1

Ok, grundlegend fehlte mir der Mechanismus, wie HTTP funktioniert. Nach einigen Tagen des Studiums habe ich verstanden, dass die richtige Vorgehensweise httr Paket den unten gezeigten Weg verwendet.

Als erstes habe ich alle Einstellungen abgerufen aus der öffentlichen Seite benötigt:

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

Dann ist es möglich, die POST-Anforderung an die Zielseite zu starten:

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

Das ist es!