rvest
Сегодня мы будем сгружать данные с html-страницы. Для этого нам понадобится библиотека rvest
. Установим её:
install.packages("rvest")
И загрузим:
library(rvest)
Теперь, когда у нас всё готово к работе, зайдём на сайт N+1 и посмотрим на исходный код его главной страницы. Нас будут интересовать новости за последнее время — те, что отображаются на главной странице. Для начала выберем какую-нибудь одну новость и напишем универсальный код для выгрузки информации с неё (а потом сможем написать функцию и применить её к ссылкам на новости в цикле). Сохраним ссылку и считаем код со страницы:
url <-'https://nplus1.ru/news/2019/05/23/cosmoquest'
page <- read_html(url)
page
## {xml_document}
## <html class="no-js bg-fixed _no-bg" style="background-image:url(https://nplus1.ru/images/2019/05/23/2138c00faaeeafb3e80529ca0481a42b.jpg)" lang="">
## [1] <head>\n<meta http-equiv="Content-Type" content="text/html; charset= ...
## [2] <body style="background-image:url(https://nplus1.ru/images/2019/05/2 ...
Результат выше — полный html-код в «свёрнутом» виде. Теперь в пределах этого кода мы будем искать нужные нам тэги. Библиотека rvest
имеет особый синтаксис, унаследованный от magrittr
, а именно, pipes, которые мы встречали в dplyr
и tidyverse
: %>%
. Найдём в объекте page
все тэги <a>
:
page %>%
html_nodes("a")
## {xml_nodeset (80)}
## [1] <a href="#" class="action-menu pull-left"><i class="icon icon-navic ...
## [2] <a href="/" class="link-logo"><img src="/i/logo-mobile.png"></a>
## [3] <a href="#" class="action-search pull-right"><i class="icon icon-se ...
## [4] <a href="#" class="action-search-close">×</a>
## [5] <a href="/rubric/astronomy" class="">Астрономия</a>
## [6] <a href="/rubric/physics" class="">Физика</a>
## [7] <a href="/rubric/biology" class="">Биология</a>
## [8] <a href="/rubric/robots-drones" class="">Роботы и дроны</a>
## [9] <a href="/theme/oops" class="">Научные закрытия</a>
## [10] <a href="/theme/economy-literature" class="">Краткий курс по литэко ...
## [11] <a href="/theme/hayabusa" class="">Приключения «Хаябусы-2»</a>
## [12] <a href="/theme/art-of-integration" class="">Интегрирование — искус ...
## [13] <a href="/" class="link-logo"></a>
## [14] <a href="#" class="action-search-close">×</a>
## [15] <a href="/rubric/astronomy" class="">Астрономия</a>
## [16] <a href="/rubric/physics" class="">Физика</a>
## [17] <a href="/rubric/biology" class="">Биология</a>
## [18] <a href="/rubric/robots-drones" class="">Роботы и дроны</a>
## [19] <a href="#" class="action-search"><i class="icon icon-search"></i></a>
## [20] <a href="/theme/oops" class="">Научные закрытия</a>
## ...
Теперь найдём все части кода с тэгом <p>
и посмотрим на первые 10 элементов:
page %>%
html_nodes("p") %>%
head(10)
## {xml_nodeset (10)}
## [1] <p class="table">\n <a data-rubric="astronom ...
## [2] <p class="table">\n <a href="/news/2019/05/23">\n ...
## [3] <p class="table">\n <a href="/difficult/1.2">\n ...
## [4] <p class="title"></p>
## [5] <p class="credits">NASA</p>
## [6] <p>Стартовал проект Bennu Mappers, в рамках которого любой желающий ...
## [7] <p>Автоматическая межпланетная станция OSIRIS-REx была <a href="htt ...
## [8] <p>Задача забора образца реголита с Бенну оказалась гораздо сложнее ...
## [9] <p>Принять участие в проекте может любой желающий, имеющий доступ в ...
## [10] <p>Ранее мы <a href="https://nplus1.ru/news/2019/03/26/AstroQuest" ...
Допустим, что нам нужна следующая информация о статье: дата, время, автор, сложность и сам текст статьи. Дата, время и сложность статьи содержится в табличке перед текстом. Таблицы на этой странице имеют тэг <p>
с атрибутом class
равным table
. В rvest
класс указывается через точку, id — через #
.
page %>%
html_nodes("p.table")
## {xml_nodeset (3)}
## [1] <p class="table">\n <a data-rubric="astronomy ...
## [2] <p class="table">\n <a href="/news/2019/05/23">\n ...
## [3] <p class="table">\n <a href="/difficult/1.2">\n ...
Если посмотреть внимательнее, то из таблицы нам нужны только те части, которые заключены в тэги <span>
. Вытащим их и возьмём только текст:
page %>%
html_nodes("p.table") %>%
html_nodes("span") %>%
html_text()
## [1] "17:32" "23 Май 2019" "Сложность" "1.2"
Теперь нам осталось сохранить результат (а это обычный текстовый вектор) в переменную и извлечь оттуда нужные части:
info <- page %>%
html_nodes("p.table") %>%
html_nodes("span") %>%
html_text()
Извлечём время написания статьи, дата и сложность:
ntime <- info[1]
ndate <- info[2]
ndiff <- as.numeric(info[4])
Проверим, что получилось:
ntime
## [1] "17:32"
ndate
## [1] "23 Май 2019"
ndiff
## [1] 1.2
С текстом статьи работать будет сложнее, займёмся этим в следующий раз.