Скрейпинг таблиц и ссылок
Разбирайте таблицы HTML в таблицы данных и собирайте все гиперссылки на странице.
«Скрейпинг таблиц и ссылок» — бесплатный урок R Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.
HTML-таблицы на веб-страницах
HTML-таблицы (<table>) — наиболее удобные цели для скрейпинга, поскольку они уже имеют структуру. Функция html_table() из rvest напрямую преобразует их в таблицы данных R, автоматически обрабатывая заголовки.
library(rvest)
html <- read_html('
<table>
<thead><tr><th>Country</th><th>GDP</th><th>Pop</th></tr></thead>
<tbody>
<tr><td>USA</td><td>25T</td><td>330M</td></tr>
<tr><td>China</td><td>18T</td><td>1400M</td></tr>
</tbody>
</table>
')
# html_table converts to data frame
tbl <- html_table(html_element(html, 'table'))
class(tbl) # 'data.frame'
names(tbl) # c('Country', 'GDP', 'Pop')
nrow(tbl) # 2
print(tbl)html_table() для всей страницы
Если на странице несколько таблиц, используйте html_elements() (множественное число), чтобы получить все таблицы, а затем примените html_table() к полученному набору узлов, чтобы вернуть список таблиц данных. Выберите нужную таблицу по индексу.
library(rvest)
html <- read_html('
<table id="t1"><tr><th>A</th></tr><tr><td>1</td></tr></table>
<table id="t2"><tr><th>X</th><th>Y</th></tr>
<tr><td>10</td><td>20</td></tr></table>
')
# Get ALL tables as a list of data frames
tables <- html_table(html_elements(html, 'table'))
length(tables) # 2
# First table
tables[[1]]
# Second table
tables[[2]]
# Select a specific table by its id
table2 <- html_table(html_element(html, '#t2'))
print(table2)Очистка данных таблицы
В таблицах, собранных с веб-сайтов, часто встречаются неаккуратные заголовки, объединённые ячейки или лишние пробелы. Используйте janitor::clean_names() для заголовков, а стандартные операции dplyr/stringr — для очистки значений ячеек.
library(rvest)
html <- read_html('
<table>
<tr><th>Product Name</th><th>Price (USD)</th><th>In Stock?</th></tr>
<tr><td> Widget A </td><td>$12.50</td><td>Yes</td></tr>
<tr><td>Gadget B</td><td>$7.99</td><td>No</td></tr>
</table>
')
df <- html_table(html_element(html, 'table'))
# Clean column names
names(df) <- c('product', 'price', 'in_stock')
# Strip whitespace and dollar signs
df$product <- trimws(df$product)
df$price <- as.numeric(gsub('[$]', '', df$price))
df$in_stock <- df$in_stock == 'Yes'
print(df)Сбор всех ссылок на странице
Ссылки — это теги-якоря (<a>) с атрибутами href. Используйте html_elements(page, 'a'), чтобы получить все якоря, затем html_attr('href') — для URL, а html_text2() — для текста ссылок.
library(rvest)
html <- read_html('
<div>
<a href="/about">About Us</a>
<a href="/products">Products</a>
<a href="https://partner.com" rel="external">Partner</a>
<a>No href link</a>
</div>
')
# Get all anchor elements
anchors <- html_elements(html, 'a')
# Extract text and href
link_text <- html_text2(anchors)
link_href <- html_attr(anchors, 'href')
data.frame(text = link_text, href = link_href)
# Note: last row has NA hrefФильтрация значимых ссылок
На настоящих страницах навигационные ссылки, ссылки в нижнем колонтитуле и внутренние якоря перемешаны со ссылками, которые Вам действительно нужны. Удалите NA, якоря (#) и ссылки javascript:, а затем примените сопоставление с шаблоном, чтобы оставить только нужные URL.
library(rvest)
html <- read_html('
<div>
<a href="/article/1">Article One</a>
<a href="/article/2">Article Two</a>
<a href="#top">Back to top</a>
<a href="javascript:void(0)">JS link</a>
<a href="/article/3">Article Three</a>
</div>
')
anchors <- html_elements(html, 'a')
hrefs <- html_attr(anchors, 'href')
texts <- html_text2(anchors)
# Keep only article links
article_idx <- grepl('^/article/', hrefs) & !is.na(hrefs)
article_links <- data.frame(
text = texts[article_idx],
href = hrefs[article_idx]
)
print(article_links)От относительных URL к абсолютным
Извлечённые значения href часто являются относительными путями, например /page. Преобразуйте их в абсолютные URL, добавив базовый URL. Функция xml2::url_absolute() корректно выполняет это преобразование.
library(rvest)
base_url <- 'https://books.toscrape.com'
html <- read_html('
<ul>
<li><a href="/catalogue/book1">Book One</a></li>
<li><a href="/catalogue/book2">Book Two</a></li>
<li><a href="https://external.com/book">External</a></li>
</ul>
')
hrefs <- html_attr(html_elements(html, 'a'), 'href')
# xml2::url_absolute resolves relative + keeps absolute
abs_urls <- xml2::url_absolute(hrefs, base = base_url)
abs_urls
# 'https://books.toscrape.com/catalogue/book1'
# 'https://books.toscrape.com/catalogue/book2'
# 'https://external.com/book' <- kept as-isЦелевой сбор ссылок
Вместо того чтобы собирать все ссылки и затем фильтровать их, используйте конкретные селекторы CSS, чтобы сразу выбрать только нужные ссылки. Для точности сочетайте контекст элемента и селекторы атрибутов.
library(rvest)
html <- read_html('
<nav class="breadcrumb">
<a href="/">Home</a> > <a href="/books">Books</a>
</nav>
<ul class="products">
<li><a href="/books/1" class="prod-link">Clean Code</a></li>
<li><a href="/books/2" class="prod-link">Refactoring</a></li>
</ul>
<footer>
<a href="/privacy">Privacy</a>
</footer>
')
# Target ONLY product links (not nav or footer)
prod_links <- html_elements(html, 'ul.products a.prod-link')
data.frame(
title = html_text2(prod_links),
url = html_attr(prod_links, 'href')
)Объединение данных таблиц и ссылок
Нередко ячейки таблицы содержат ссылки. Объединяйте html_table() для получения текстовых значений и целевой вызов html_attr() для встроенных ссылок, чтобы создать более информативную таблицу данных.
library(rvest)
html <- read_html('
<table class="results">
<tr><th>Book</th><th>Author</th></tr>
<tr>
<td><a href="/b/1">Clean Code</a></td>
<td>Robert Martin</td>
</tr>
<tr>
<td><a href="/b/2">Refactoring</a></td>
<td>Martin Fowler</td>
</tr>
</table>
')
# Get text from table
df <- html_table(html_element(html, 'table'))
# Get links embedded in first column
links <- html_attr(html_elements(html, 'table td a'), 'href')
df$url <- links
print(df)Параметр fill функции html_table()
В HTML-таблицах иногда встречаются отсутствующие ячейки или строки с нерегулярной структурой. Параметр fill=TRUE функции html_table() заполняет отсутствующие значения значением NA вместо создания ошибки.
library(rvest)
html <- read_html('
<table>
<tr><th>Name</th><th>Score</th><th>Grade</th></tr>
<tr><td>Alice</td><td>95</td><td>A</td></tr>
<tr><td>Bob</td><td>80</td></tr>
</table>
')
# Without fill=TRUE this may error on uneven rows
df <- html_table(html_element(html, 'table'), fill = TRUE)
print(df)
# Name Score Grade
# Alice 95 A
# Bob 80 <NA>
# fill=TRUE is safe even when rows are uniform
is.na(df[2, 'Grade']) # TRUEИзвлечение источников изображений
Изображения используют атрибуты src (а иногда data-src для отложенной загрузки). Тот же подход с html_attr() позволяет извлекать URL изображений для скачивания или каталогизации.
library(rvest)
html <- read_html('
<div class="gallery">
<img src="/img/photo1.jpg" alt="Sunset">
<img src="/img/photo2.jpg" alt="Mountains">
<img data-src="/img/lazy.jpg" class="lazy" alt="Lake">
</div>
')
# Regular images
images <- html_elements(html, 'img')
srcs <- html_attr(images, 'src')
alts <- html_attr(images, 'alt')
data.frame(alt = alts, src = srcs)
# For lazy-loaded images check data-src
lazy_src <- html_attr(html_element(html, '.lazy'), 'data-src')
lazy_src # '/img/lazy.jpg'Сохранение собранных данных
После сбора таблиц и ссылок в таблицу данных сохраните результаты с помощью write.csv() или readr::write_csv(). Всегда добавляйте отметку времени или исходный URL, чтобы сохранять сведения о происхождении данных.
library(rvest)
html <- read_html('
<table>
<tr><th>Product</th><th>Price</th></tr>
<tr><td>Widget</td><td>9.99</td></tr>
<tr><td>Gadget</td><td>14.50</td></tr>
</table>
')
df <- html_table(html_element(html, 'table'))
# Add metadata
df$scraped_at <- Sys.time()
df$source_url <- 'https://example.com/products'
# Save to CSV
# write.csv(df, 'products.csv', row.names = FALSE)
print(df)
cat('Data ready for analysis or storage')Быстрая проверка
Проверьте, насколько хорошо Вы понимаете сбор HTML-таблиц и ссылок с помощью rvest.
Итоги: таблицы и ссылки
Главное: html_table() автоматически преобразует HTML-таблицы в таблицы данных; используйте fill=TRUE для таблиц с нерегулярной структурой. Для ссылок получите все якоря с помощью html_elements('a'), текст — с помощью html_text2(), а URL — с помощью html_attr('href'). Преобразуйте относительные URL в абсолютные с помощью xml2::url_absolute(). Фильтруйте ненужные ссылки по шаблону. Объединяйте текст таблицы и URL встроенных ссылок, чтобы получить более информативные наборы данных.
library(rvest)
# Table scraping pattern:
# tables <- html_table(html_elements(page, 'table'))
# df <- tables[[1]]
# Link scraping pattern:
# links <- html_elements(page, 'a[href]')
# data.frame(
# text = html_text2(links),
# url = xml2::url_absolute(
# html_attr(links, 'href'),
# base = base_url
# )
# )
# Combine: scrape table text AND embedded link URLs
cat('Tables + links = most of what the web offers')Часто задаваемые вопросы
Урок «Скрейпинг таблиц и ссылок» бесплатный?
Да — полный текст урока «Скрейпинг таблиц и ссылок» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.
Чему я научусь в уроке «Скрейпинг таблиц и ссылок»?
Разбирайте таблицы HTML в таблицы данных и собирайте все гиперссылки на странице. Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать R Academy?
Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Скрейпинг таблиц и ссылок»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке R Academy?
Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Структура HTML и селекторы CSS
- Основы html_element() и html_text()
- Скрейпинг таблиц и ссылок
- Обработка разбивки на страницы и нескольких страниц