Я пытаюсь скопировать таблицу с веб-страницы, их будет много, поскольку я пытаюсь получить версии данных для каждого набора данных. Я пытаюсь получить хотя бы одну таблицу, но безуспешно. Парсинг - это не мой конёк, может быть и очевидно, как его получить, но не для меня.
Вот мой код:
url <- "https://data.cms.gov/provider-characteristics/medicare-provider-supplier-enrollment/medicare-fee-for-service-public-provider-enrollment/api-docs"
html <- rvest::read_html(url)
> html |> rvest::html_node(".table")
{xml_missing}
<NA>
И
> html |>
rvest::html_node(xpath = "/html/body/div/div/div/div/div/div/div[2]/div[2]/div/div/table/tbody")
{xml_missing}
<NA>
И
html |>
rvest::html_node("tbody")
Вывод показал, что необходимо включить JavaScript. Первый ответ работает для текущего набора данных, а второй ответ, который я опубликовал, работает для большинства дистрибутивов, в которых в выходных данных присутствуют accessURL и заголовок.






К сожалению, этот подход не сработает. Таблицы на странице, которую вы просматриваете, генерируются с помощью JavaScript. Вызов rvest::read_html(url) получит статический контент на этой странице, но не выполнит какой-либо (динамический) JavaScript.
Но за сайтом стоит API, поэтому вы можете получать данные непосредственно оттуда. Например:
library(httr)
params = list(
`path` = "/provider-characteristics/medicare-provider-supplier-enrollment/medicare-fee-for-service-public-provider-enrollment"
)
res <- httr::GET(url = "https://data.cms.gov/data-api/v1/slug", query = params)
cat(content(res, as = "text", encoding = "UTF-8"))
В качестве альтернативы вы можете использовать что-то вроде {RSelenium}, чтобы оценить JavaScript, а затем очистить полностью отрисованную страницу.
Я также смог получить большую часть того, что хотел, выполнив следующие действия:
url <- "https://data.cms.gov/data.json"
data_sets <- httr2::request(url) |>
httr2::req_perform() |>
httr2::resp_body_json(check_type = FALSE, simplifyVector = TRUE)
data_tbl <- data_sets$dataset |>
dplyr::tibble() |>
dplyr::select(title, modified, keyword, description, contactPoint, identifier) |>
tidyr::unnest(cols = c(keyword, contactPoint)) |>
dplyr::select(-`@type`) |>
dplyr::mutate(hasEmail = stringr::str_remove(hasEmail, "mailto:"))
data_distribtution <- function(.data){
df <- .data
dplyr::tibble(data = df[["dataset"]][["distribution"]]) |>
dplyr::mutate(cnm = purrr::map(data, \(x) names(x))) |>
dplyr::mutate(title_in_col = purrr::map(cnm, \(x) "title" %in% x) |> unlist()) |>
dplyr::mutate(accessURL_in_col = purrr::map(cnm, \(x) "accessURL" %in% x) |> unlist()) |>
dplyr::filter(title_in_col == TRUE & accessURL_in_col == TRUE) |>
dplyr::select(data) |>
dplyr::mutate(data = purrr::map(
data, \(x) x |>
dplyr::select(title, modified, temporal, accessURL,
downloadURL, mediaType) |>
dplyr::mutate(data_link = dplyr::coalesce(accessURL, downloadURL)) |>
dplyr::mutate(mediaType = ifelse(is.na(mediaType), "api", mediaType)) |>
dplyr::mutate(modified = as.Date(modified)) |>
dplyr::select(-accessURL, -downloadURL) |>
dplyr::arrange(dplyr::desc(modified), mediaType)
)) |>
tidyr::unnest(cols = c(data))
}
Пример вывода
> data_distribtution(.data = data_sets) |>
+ head(1) |>
+ dplyr::glimpse()
Rows: 1
Columns: 5
$ title <chr> "Accountable Care Organization Participants : 2024-01-24"
$ modified <date> 2024-01-29
$ temporal <chr> "2024-01-01/2024-12-31"
$ mediaType <chr> "api"
$ data_link <chr> "https://data.cms.gov/data-api/v1/dataset/9767cb68-8ea9-4f0b-8179-9431abc89f1…
Что показывает вывод
html? Появляется ли сообщение: «Для запуска этого приложения необходимо включить JavaScript»? Если да, то вы можете рассмотреть возможность использованияRSelenium.