R: Машина обратного пути для очистки веб-страниц

Я работаю с языком программирования R.

Для следующего веб-сайта: https://covid.cdc.gov/covid-data-tracker/ — я пытаюсь получить все версии этого веб-сайта, доступные на WayBackMachine (вместе с месяцем и временем). Окончательный результат должен выглядеть примерно так:

         date                                                                                links     time
1 Jan-01-2023 https://web.archive.org/web/20230101000547/https://covid.cdc.gov/covid-data-tracker/ 00:05:47
2 Jan-01-2023 https://web.archive.org/web/20230101000557/https://covid.cdc.gov/covid-data-tracker/ 00:05-57

Вот что я пробовал до сих пор:

Шаг 1: Сначала я проверил исходный код HTML (внутри «элементов») и скопировал/вставил его в файл блокнота:

Шаг 2: Затем я импортировал это в R и проанализировал полученный html для структуры ссылок:

file <- "cdc.txt"

text <- readLines(file)

html <- paste(text, collapse = "\n")

pattern1 <- '/web/\\d+/https://covid\\.cdc\\.gov/covid-data-tracker/[^"]+'

links <- regmatches(html, gregexpr(pattern1, html))[[1]]

Но это не работает:

> links
character(0)

Может кто-нибудь показать мне, есть ли более простой способ сделать это?

Спасибо!

Примечание:

  • Я пытаюсь узнать, как это сделать в целом (т. е. для любых веб-сайтов на WayBackMachine — Covid Data Tracker — это просто пример-заполнитель для этого вопроса)

  • Я понимаю, что могут быть гораздо более эффективные способы сделать это - я открыт для изучения различных подходов!

Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
3
0
100
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это действительно два вопроса. HTML создается на стороне клиента, а не на стороне сервера. Вот почему вы не можете просто запросить html из R, чтобы получить то, что вам нужно, и в конечном итоге скопировать и вставить из инструментов разработчика. Вы можете автоматизировать это с помощью RSelenium. Документы обширны, поэтому я не буду освещать это в ответе.

Вы также должны использовать синтаксический анализатор, такой как rvest , для разбора HTML, а не регулярные выражения. В этом случае, чтобы получить желаемый результат, это будет выглядеть примерно так:

library(rvest)

url <- "wayback.html"
page <- read_html(url)

# Find correct links
links <- page |>
    html_elements("a") |>
    html_attr("href") |>
    grep("/web/\\d.+/https://covid.cdc.gov/covid-data-tracker/$", x = _, value = T)

# Create dates
dates <- as.Date(
    gsub("/web/(\\d{8}).+$", "\\1", links),
    format = "%Y%m%d"
)

# Prepend base URL
links <- paste0("https://web.archive.org/", links)

dat <- data.frame(dates, links)
head(dat)

#        dates                                                                                 links
# 1 2020-08-24 https://web.archive.org//web/20200824224244/https://covid.cdc.gov/covid-data-tracker/
# 2 2023-06-30 https://web.archive.org//web/20230630234650/https://covid.cdc.gov/covid-data-tracker/
# 3 2023-06-29 https://web.archive.org//web/20230629011221/https://covid.cdc.gov/covid-data-tracker/
# 4 2023-01-01       https://web.archive.org//web/20230101/https://covid.cdc.gov/covid-data-tracker/
# 5 2023-01-02       https://web.archive.org//web/20230102/https://covid.cdc.gov/covid-data-tracker/
# 6 2023-01-03       https://web.archive.org//web/20230103/https://covid.cdc.gov/covid-data-tracker/

@ SamR: Большое спасибо за ответ! Я попытался запустить ваш код и получил следующие ошибки:

stats_noob 02.07.2023 00:59

> библиотека (rvest) > > URL-адрес <- "wayback.html" > страница <- read_html (url) Ошибка: "wayback.html" не существует в текущем рабочем каталоге ("C:/Users/me/OneDrive/Documents" ). > > # Найти правильные ссылки > ссылки <- страница |> + html_elements("a") |> + html_attr("href") |> + grep("/web/\\d.+/covid.cdc. gov/covid-data-tracker/$ ", x = _, value = T) Ошибка: неожиданный ввод в: " html_attr("href") |> grep("/web/\\d.+/ covid .cdc.gov/covid-data-tracker/$", x = _"

stats_noob 02.07.2023 00:59

Нужно ли заменить URL-адрес <- "" фактическим веб-сайтом?

stats_noob 02.07.2023 01:00

Нет, это не сработает. Вам понадобится селен, если вы хотите это сделать. Это скопированный и вставленный HTML-код, который вы сохранили как cdc.txt. Я должен был сделать это яснее.

SamR 02.07.2023 10:14
Ответ принят как подходящий

Archive.org предоставляет Wayback CDX API для поиска захватов, он возвращает временные метки вместе с исходными URL-адресами в табличной форме или JSON. Такие запросы можно делать только с помощью read.table(), а затем создавать ссылки на определенные захваты из столбцов timestamp и original и базового URL-адреса.

read.table("https://web.archive.org/cdx/search/cdx?url=covid.cdc.gov/covid-data-tracker/&limit=5", 
           col.names = c("urlkey","timestamp","original","mimetype","statuscode","digest","length"),
           colClasses = "character")
#>                              urlkey      timestamp
#> 1 gov,cdc,covid)/covid-data-tracker 20200824224244
#> 2 gov,cdc,covid)/covid-data-tracker 20200825013347
#> 3 gov,cdc,covid)/covid-data-tracker 20200825024622
#> 4 gov,cdc,covid)/covid-data-tracker 20200825042657
#> 5 gov,cdc,covid)/covid-data-tracker 20200825050018
#>                                    original  mimetype statuscode
#> 1 https://covid.cdc.gov/covid-data-tracker/ text/html        200
#> 2 https://covid.cdc.gov/covid-data-tracker/ text/html        200
#> 3 https://covid.cdc.gov/covid-data-tracker/ text/html        200
#> 4 https://covid.cdc.gov/covid-data-tracker/ text/html        200
#> 5 https://covid.cdc.gov/covid-data-tracker/ text/html        200
#>                             digest length
#> 1 APS6SXNXBXCJU3P4N23WH4XCVDVZQYAD   5342
#> 2 XFEMFRGXIPWM4K5F6CBIYDSOFIGCUBQZ   5370
#> 3 TVQKZHRM452CFX4RIORWGSMK5PG3PAPR   5343
#> 4 XZDLPJ6EQIXEO4SUFQTFEX4S6SF7O4GT   5370
#> 5 A4J63TFU7HMZQE5KFTSLBD6EFNZ4IBZ4   5373

Чтобы было немного удобнее работать, мы можем настроить запрос API с помощью httr / httr2, например, и передать ответ через конвейер readr / dplyr / lubridate:

library(dplyr)
library(httr2)
library(readr)

archive_links <- request("https://web.archive.org/cdx/search/cdx") %>% 
  # set query parameters
  req_url_query(
    url      = "covid.cdc.gov/covid-data-tracker/",
    filter   = "statuscode:200", # include only succesful captures where HTTP status code was 200
    collapse = "timestamp:8",    # limit to 1 capt. per day by comparing first 8 digits of timestamp: <20200824>224244
    limit    = 10,               # limit the number of returned values
    # output = "json"            # request json output, includes column names
  ) %>% 
  req_perform() %>%
  # pass http response string to read_table() for pasring
  resp_body_string() %>% 
  read_table(col_names = c("urlkey","timestamp","original","mimetype","statuscode","digest","length"),
             col_types = cols_only(timestamp = "c",
                                   original  = "c",
                                   mimetype  = "c",
                                   length    = "i")) %>% 
  mutate(link = paste("https://web.archive.org/web", timestamp, original, sep = "/") %>% tibble::char(shorten = "front"),
         timestamp = lubridate::ymd_hms(timestamp)) %>% 
  select(timestamp, link, length)
archive_links
#> # A tibble: 10 × 3
#>    timestamp           link                                               length
#>    <dttm>              <char>                                              <int>
#>  1 2020-08-24 22:42:44 …4224244/https://covid.cdc.gov/covid-data-tracker/   5342
#>  2 2020-08-25 01:33:47 …5013347/https://covid.cdc.gov/covid-data-tracker/   5370
#>  3 2020-08-26 02:37:09 …6023709/https://covid.cdc.gov/covid-data-tracker/   5371
#>  4 2020-08-27 01:05:48 …7010548/https://covid.cdc.gov/covid-data-tracker/   5703
#>  5 2020-08-28 02:23:26 …8022326/https://covid.cdc.gov/covid-data-tracker/  31177
#>  6 2020-08-29 02:01:27 …9020127/https://covid.cdc.gov/covid-data-tracker/  31237
#>  7 2020-08-30 00:06:31 …0000631/https://covid.cdc.gov/covid-data-tracker/  31218
#>  8 2020-08-31 00:18:29 …1001829/https://covid.cdc.gov/covid-data-tracker/  31640
#>  9 2020-09-01 02:30:30 …1023030/https://covid.cdc.gov/covid-data-tracker/  31257
#> 10 2020-09-02 04:08:31 …2040831/https://covid.cdc.gov/covid-data-tracker/  31654

# first capture:
archive_links$link[1]
#> <pillar_char<[1]>
#> [1] https://web.archive.org/web/20200824224244/https://covid.cdc.gov/covid-data-tracker/

Created on 2023-07-02 with reprex v2.0.2

Существуют также клиентские библиотеки Archive.org для R, например. https://github.com/liserman/archiveRetriever & https://hrbrmstr.github.io/wayback/ , хотя интерфейс запроса для первого немного странный, а другой в настоящее время недоступен через КРАН.

@margsul: большое спасибо за ответ! API в этом случае бесплатное? И это не требует от вас даже регистрации учетной записи? Спасибо!

stats_noob 02.07.2023 15:12

Насколько мне известно, доступ CDX к общедоступным данным никоим образом не ограничен, не уверен, что я бы назвал его «бесплатным» — пожертвования поддерживают его работу, а archive.org приветствует всех сторонников.

margusl 03.07.2023 10:28

Другие вопросы по теме