从数据 link 为数据的网页下载 csv 文件的 R 脚本:text/csv

R script to download csv file from a web page where the data link is of data:text/csv

我正在尝试编写一个可以从以下网站下载 csv 文件的 R 脚本,"https://www.covidanalytics.io/projections 页面底部有一个 link 用于下载数据,需要"data:text/csv..." 的形式。我想知道我是否可以有一个 R 脚本来下载 csv 格式的文件。任何帮助将不胜感激。

谢谢 IC

有更简单的方法来获取这些数据,但是 可以使用 httr 包进行一些 low-level 的工作。

正如@r2evans 所指出的,这是一个由 Dash 构建的 url-encoded csv。要获取 url,您需要使用 xhr 请求请求包含 html 页面信息的 json 文件。这需要所有正确的 headers 以及 POST 请求的 body 中的 json 请求:

library(httr)

page1 <- GET("https://www.covidanalytics.io/projections")

H <- add_headers( `Host` = "www.covidanalytics.io",
                  `User-Agent` = paste("Mozilla/5.0 (Windows NT 6.1; rv:77.0)", 
                                       "Gecko/20100101 Firefox/77.0"),
                  `Accept` = "application/json",
                  `Accept-Language` = "en-GB,en;q=0.5",
                  `Accept-Encoding` = "gzip, deflate",
                  `Referer` = "https://www.covidanalytics.io/projections",
                  `Content-Type` = "application/json",
                  `X-CSRFToken` = "undefined",
                  `Origin` = "https://www.covidanalytics.io",
                  `Connection` = "keep-alive")

post_data <- paste0('{"output":"page-content.children","outputs":{"id":',
                    '"page-content","property":"children"},"inputs":',
                    '[{"id":"url","property":"pathname","value":',
                    '"/projections"}],"changedPropIds":["url.pathname"]}')

res <- httr::POST("https://www.covidanalytics.io/_dash-update-component", H,
                  body = post_data, encode = "raw")

'res` 现在包含 json 响应,我们的 url-encoded csv 位于其中。我们得到这个解析后的内容并提取包含 url:

的字符串
body <- parsed_content(res)$response$`page-content`$children$props$children[[2]]
div <- body$props$children[[10]]$props$children[[1]]
url <- div$props$children$props$children$props$href

现在我们需要截掉data:text/csv;charset=utf-8,部分,并对url编码进行反转义。我实际上发现使用嵌套 gsubs 速度要快得多,因为我的机器在 URLdecode:

上卡住了
csv <- strsplit(url, ",")[[1]][2]
df <- read.csv(text = gsub("%0A", "\n", gsub("%20", " ", gsub("%2C", ",", csv))))

您的数据现在在 df。它很大,所以我会在这里显示它:

tidyr::as_tibble(df)
#> # A tibble: 7,106 x 10
#>    Continent Country Province Day   Total.Detected Active Active.Hospital~ Cumulative.Hosp~
#>    <fct>     <fct>   <fct>    <fct> <fct>           <int>            <int>            <int>
#>  1 Africa    Algeria None     2020~ 5651             1531              302              834
#>  2 Africa    Algeria None     2020~ 5742             1514              300              848
#>  3 Africa    Algeria None     2020~ 5831             1497              298              861
#>  4 Africa    Algeria None     2020~ 5917             1477              296              874
#>  5 Africa    Algeria None     2020~ 6000             1457              293              886
#>  6 Africa    Algeria None     2020~ 6079             1435              291              898
#>  7 Africa    Algeria None     2020~ 6156             1411              287              910
#>  8 Africa    Algeria None     2020~ 6230             1387              284              921
#>  9 Africa    Algeria None     2020~ 6300             1361              280              932
#> 10 Africa    Algeria None     2020~ 6368             1335              277              942
#> # ... with 7,096 more rows, and 2 more variables: Total.Detected.Deaths <int>,
#> #   Active.Ventilated <int>