如何使用 R 抓取 Amcharts 交互式数据

问题描述 投票:0回答:1

我正在尝试从以下链接检索数据,但我注意到数据位于交互式 Amcharts 1.1 中。 我找不到 GET 或 POST 方法的最佳参数。我认为该网站正在使用另一个流程来发布数据。

有人可以提供一些见解吗?我们将非常感谢您的帮助。

library(httr)
library(rvest)
library(XML)
url <- 'https://live.euronext.com/en/product/equities/FR0004040608-XPAR'

page <- read_html(url)

class(page)
# "xml_document" "xml_node" 

xml_child(page, 2)
# {html_node}
# <body class="layout-no-sidebars path-product">
# [1] <a href="#main-content" class="visually-hidden focusable skip-link">\n   ...
# [2] <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-T ...
# ....
# [20] <script src="/sites/default/files/js/optimized/js_gcfptZrWxdKuaT414lrcjk ...


> page %>% html_nodes(xpath = '//*[@id="price-chart"]')%>% html_text()
# character(0)

page %>% html_nodes("script")%>% html_text()

page %>% html_nodes("noscript")%>% html_text()
# [1] "form.antibot * :not(.antibot-message) { display: none !important; }"
# [2] ""  

开发工具部分的图片 After i clicked on Max

The format of the response does not contain data

Data are in a svg

r xml rvest amcharts httr
1个回答
0
投票

您已成功识别数据源,它看起来有点神秘,因为它实际上是加密的(或“加密的”,至少不仅仅是base64编码的)。

尽管预处理图表数据的函数

ajax_secure_dataFilter()
也可以在浏览器会话中调用。因此,如果我们选择惰性路由并将
chromote
添加到此组合中,我们可以将其指向该站点,以便它首先为我们加载所有 JavaScript 要求,然后我们可以创建一个小型 js 辅助函数,该函数将在 Chrome 中获取 json会话并在获取的图表数据上调用
ajax_secure_dataFilter()

最后,我们可以使用 R 中的任何图表数据端点调用该 js 函数,将解码后的 JSON 作为列表列表并将其整理成平面框架。

library(ggplot2)
library(dplyr)
library(chromote)
library(stringr)

url_ <- "https://live.euronext.com/en/product/equities/FR0004040608-XPAR"
chart_max <- str_glue("https://live.euronext.com/en/intraday_chart/getChartData/{basename(url_)}/max")

b <- ChromoteSession$new()
{
  b$Page$navigate("https://live.euronext.com/en/product/equities/FR0004040608-XPAR")
  b$Page$loadEventFired()
} 
#> $timestamp
#> [1] 522961.4

# create js function that fetches chart data and passes it though ajax_secure_dataFilter() 
b$Runtime$evaluate("function fetch_chart_data(url) {return fetch(url).then(response => response.json()).then(json => ajax_secure_dataFilter(json, 'json', false))}")
#> $result
#> $result$type
#> [1] "undefined"

# call it with chart data url
chart_data <- b$Runtime$evaluate(str_glue('fetch_chart_data("{chart_max}")'), awaitPromise = TRUE, returnByValue = TRUE)$result$value
head(chart_data, n = 3) |> str()
#> List of 3
#>  $ :List of 3
#>   ..$ time  : chr "1999-09-01 02:00"
#>   ..$ price : num 9.7
#>   ..$ volume: int 25810
#>  $ :List of 3
#>   ..$ time  : chr "1999-09-02 02:00"
#>   ..$ price : num 9.75
#>   ..$ volume: int 17430
#>  $ :List of 3
#>   ..$ time  : chr "1999-09-03 02:00"
#>   ..$ price : num 9.85
#>   ..$ volume: int 28270

# list to frame, parse date/time
chart_data_df <- 
  chart_data |>
  bind_rows(chart_data) |>
  mutate(time = lubridate::ymd_hm(time))

结果:

chart_data_df
#> # A tibble: 12,480 × 3
#>    time                price volume
#>    <dttm>              <dbl>  <dbl>
#>  1 1999-09-01 02:00:00  9.7   25810
#>  2 1999-09-02 02:00:00  9.75  17430
#>  3 1999-09-03 02:00:00  9.85  28270
#>  4 1999-09-06 02:00:00 10.1   57750
#>  5 1999-09-07 02:00:00 10.2   29830
#>  6 1999-09-08 02:00:00 10.0   13700
#>  7 1999-09-09 02:00:00 10.1   17560
#>  8 1999-09-10 02:00:00 10.2    7290
#>  9 1999-09-13 02:00:00 10.2   10040
#> 10 1999-09-14 02:00:00 10.2   12220
#> # ℹ 12,470 more rows

ggplot(chart_data_df, aes(x = time)) +
  geom_area(aes(y = price, fill = "price")) +
  scale_x_datetime(breaks = "5 years") +
  theme_minimal()

创建于 2024-05-28,使用 reprex v2.1.0

© www.soinside.com 2019 - 2024. All rights reserved.