Данные соскабливаются из графика JavaScript в R - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь автоматизировать получение данных из Рисунок 1: Потребление электроэнергии относительно 2019 в этой статье . У меня нет проблем с очисткой обычной страницы, но эта диаграмма сделана в JS, и я не знаю, как действовать и где найти данные, которые использует диаграмма.

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Это относительно сложная работа по очистке. Данные, которые вы ищете, находятся на странице, на которую ссылается Eri c Truett. Он имеет формат строки JSON, которая скрыта в тексте вызова Javascript. Таким образом, вам необходимы следующие шаги:

  1. Определите страницу, которая действительно содержит данные (как уже было сделано @EricTruett)
  2. Получите страницу html в виде текстовой строки
  3. Удалите нужную часть строки
  4. Разберите JSON
  5. Получите элемент результирующего списка, который содержит нужные вам данные
  6. Преобразовать этот элемент в желаемый формат

Я могу показать вам, как делать шаги 2, 3 и 4, но шаги 5 и 6 зависят от того, каким именно должен быть ваш результат, который у вас нет не указано в вашем вопросе. Я только что угадал:

# Step 1: Get the correct url (usually done via developer tools in a browser)
uri <- "https://e.infogram.com/8dc2a0f6-6c05-4e0a-91c3-4122c56989d9?src=embed"

# Step 2: Read the html into memory as a single text string:
page <- paste(readLines(uri), collapse = "\n")

# Step 3: Strip out the JSON you need. This can only really be done by scanning the
#         html for the data you want and finding unique delimiters at either end,
#         carving out the string with regexes and tidying up either end if needed.
page <- strsplit(page, "\"data\":\\[{3}", useBytes = TRUE)[[1]][2]
json <- paste0("[[[", strsplit(page, "]]]", useBytes = TRUE)[[1]][1], "]]]")

# Step 4: Parse the JSON. Use an existing library such as jsonlite for this
map_data <- jsonlite::fromJSON(json)

# Step 5: Find the element(s) you want in the resulting data structure. Here, the
#         result is a list with several elements, and from visual inspection, element
#         9 appears to be a nice tabular array containing useful data
useful_array <- map_data[[9]]

# Step 6: Arrange the result however you like. Here, I have just selected out some
#         useful columns and converted to a tibble for pretty printing:
df <- dplyr::as_tibble(map_data[[9]][,c(1, 2, 6)])
df <- setNames(df[which(df$V2 != ""), ], c("Country", "Percent", "Change"))

И результат выглядит следующим образом:

df
#> # A tibble: 28 x 3
#>    Country  Percent Change 
#>    <chr>    <chr>   <chr>  
#>  1 Austria  90.44%  -10.00%
#>  2 Belgium  85.39%  -15.00%
#>  3 Bulgaria 94.54%  -5.00% 
#>  4 Croatia  87.16%  -13.00%
#>  5 Denmark  98.82%  -1.00% 
#>  6 Estonia  97.20%  -3.00% 
#>  7 Finland  92.40%  -8.00% 
#>  8 France   85.87%  -14.00%
#>  9 Germany  91.86%  -8.00% 
#> 10 Greece   108.48% 8.00%  
#> # ... with 18 more rows

Вам, вероятно, придется покопаться в map_data, чтобы получить актуальные данные.

1 голос
/ 06 мая 2020

На главную страницу встроена графика из https://e.infogram.com/8dc2a0f6-6c05-4e0a-91c3-4122c56989d9?src=embed. Если вы посмотрите на источник встроенной страницы, данные находятся в javascript переменной window.infographicData.

...