Структура HTML и селекторы CSS
Разберитесь в деревьях DOM и пишите селекторы CSS для выбора элементов.
«Структура HTML и селекторы CSS» — бесплатный урок R Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.
Дерево HTML DOM
Каждая веб-страница структурирована в виде дерева объектной модели документа (DOM). Элементы HTML вкладываются друг в друга, образуя иерархию «родитель — потомок». Веб-скрейпинг перемещается по этому дереву для извлечения данных.
# HTML structure conceptually:
# <html>
# <body>
# <div class='container'>
# <h1 id='title'>Hello</h1>
# <p class='text'>World</p>
# </div>
# </body>
# </html>
# rvest lets us query this tree with CSS selectors
library(rvest)
html <- read_html('<div><h1>Title</h1><p class="info">Text</p></div>')
html_text(html_element(html, 'h1'))Селектор CSS: селектор тегов
Самый простой селектор CSS выбирает элементы по их имени тега. Запись p выбирает все элементы абзацев. Запись h1 выбирает все заголовки первого уровня.
library(rvest)
html <- read_html('
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
<h2>A heading</h2>
</div>
')
# Tag selector: selects all <p> elements
nodes <- html_elements(html, 'p')
html_text2(nodes)
# Returns: c('First paragraph', 'Second paragraph')Селектор CSS: класс и ID
Используйте .classname для выбора элементов по классу и #idname для выбора уникального элемента по ID. Классы могут встречаться много раз, а ID должны быть уникальными на странице.
library(rvest)
html <- read_html('
<div>
<p class="highlight">Important text</p>
<p class="normal">Regular text</p>
<span id="price">$9.99</span>
</div>
')
# Class selector (prefix with .)
html_text2(html_element(html, '.highlight'))
# ID selector (prefix with #)
html_text2(html_element(html, '#price'))Селекторы потомков и дочерних элементов
div p выбирает любой p внутри div (на любой глубине). div > p выбирает только непосредственные дочерние элементы. h1 + p выбирает p, который сразу следует за h1 (соседний элемент).
library(rvest)
html <- read_html('
<div class="outer">
<p>Direct child</p>
<section>
<p>Nested deeper</p>
</section>
</div>
')
# Descendant: both paragraphs
all_p <- html_elements(html, 'div p')
length(all_p) # 2
# Direct child only
direct_p <- html_elements(html, 'div.outer > p')
length(direct_p) # 1Селекторы атрибутов
Селекторы атрибутов CSS позволяют выполнять фильтрацию по атрибутам HTML: [attr] проверяет наличие атрибута, [attr='val'] — точное значение, а [attr*='val'] — наличие подстроки в значении.
library(rvest)
html <- read_html('
<div>
<a href="https://example.com">External</a>
<a href="/about">Internal</a>
<a>No href</a>
</div>
')
# Select only anchors that have an href attribute
with_href <- html_elements(html, 'a[href]')
length(with_href) # 2
# Select anchors with href starting with https
external <- html_elements(html, 'a[href^="https"]')
html_text2(external) # 'External'Основы XPath
XPath — альтернатива селекторам CSS, более мощная для сложных запросов. В rvest используйте html_element(html, xpath='//tag'). //p означает любой p в любом месте, а /html/body/p — абсолютный путь.
library(rvest)
html <- read_html('
<html><body>
<table>
<tr><td class="price">10.99</td></tr>
<tr><td class="price">5.50</td></tr>
</table>
</body></html>
')
# XPath: select all td with class price
nodes <- html_elements(html, xpath = '//td[@class="price"]')
html_text2(nodes)
# c('10.99', '5.50')
# XPath text() function
nodes2 <- html_elements(html, xpath = '//td[contains(@class,"price")]')
html_text2(nodes2)Объединение селекторов
Селекторы можно объединять для большей точности. div.card h2 выбирает h2 внутри div с классом card. Запятая разделяет несколько независимых селекторов: h1, h2, h3 выбирает все три уровня заголовков.
library(rvest)
html <- read_html('
<div class="card">
<h2>Card Title</h2>
<p class="desc">Description here</p>
<span class="price">$19</span>
</div>
<div class="footer">
<h2>Footer Heading</h2>
</div>
')
# Only h2 inside .card
card_h2 <- html_element(html, 'div.card h2')
html_text2(card_h2) # 'Card Title'
# Multiple selectors with comma
price_desc <- html_elements(html, '.price, .desc')
html_text2(price_desc)Инструмент SelectorGadget
SelectorGadget — это букмарклет браузера, который помогает интерактивно находить селекторы CSS. Нажимайте на нужные элементы (они выделяются зеленым), а затем на ненужные (они выделяются красным) — инструмент автоматически создает минимальный селектор CSS.
# SelectorGadget workflow:
# 1. Open target page in Chrome/Firefox
# 2. Activate SelectorGadget bookmarklet
# 3. Click element you want -> turns green, selector appears
# 4. Click elements you DON'T want -> turns red, selector narrows
# 5. Copy the selector shown at the bottom
# 6. Use in rvest:
library(rvest)
# Example: SelectorGadget found '.product-title' for us
# page <- read_html('https://books.toscrape.com')
# titles <- html_elements(page, '.product_pod h3 a')
# html_text2(titles)
cat('SelectorGadget is available at selectorgadget.com')Проверка страниц в DevTools
DevTools браузера (F12) позволяют напрямую просматривать DOM. Щелкните правой кнопкой мыши любой элемент и выберите Inspect — на панели элементов отобразится HTML. При наведении элементы на странице подсвечиваются, что помогает определить точные тег, класс и ID, которые нужно выбрать.
# DevTools workflow for finding selectors:
# 1. F12 -> Elements tab
# 2. Click the cursor icon (Inspector)
# 3. Click the element on the page
# 4. Right-click highlighted HTML -> Copy -> Copy selector
# 5. Paste selector into rvest
# The copied selector might look like:
# '#main > div.results > article:nth-child(1) > h3'
# Simplify it: usually '.results h3' works just as well
# Validate your selector in the Console with:
# document.querySelectorAll('.results h3')
library(rvest)
cat('Always verify selectors return the elements you expect')Псевдоклассы и nth-child
Псевдоклассы CSS, такие как :first-child, :last-child и :nth-child(n), позволяют выбирать элементы по их положению внутри родительского элемента — это полезно, если у элементов нет отличительных классов.
library(rvest)
html <- read_html('
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
</ul>
')
# First item
first <- html_element(html, 'li:first-child')
html_text2(first) # 'First'
# Third item
third <- html_element(html, 'li:nth-child(3)')
html_text2(third) # 'Third'
# Even items
evens <- html_elements(html, 'li:nth-child(even)')
html_text2(evens) # c('Second', 'Fourth')Правила специфичности селекторов
Если подходит несколько селекторов, специфичность определяет, какой из них будет использован. ID важнее классов, а классы важнее тегов. При скрейпинге это имеет меньшее значение, но знание специфичности помогает создавать точные селекторы и избегать ошибочных совпадений.
library(rvest)
html <- read_html('
<div id="header" class="top">
<p class="title">Main Title</p>
</div>
<div class="content">
<p class="title">Content Title</p>
</div>
')
# Overly broad: gets BOTH titles
broad <- html_elements(html, 'p.title')
html_text2(broad)
# Specific: only header title
specific <- html_element(html, '#header p.title')
html_text2(specific) # 'Main Title'
# Be as specific as needed but not more
content_title <- html_element(html, '.content .title')
html_text2(content_title)Быстрая проверка
Проверьте, насколько хорошо Вы понимаете селекторы CSS, используемые для веб-скрейпинга с помощью rvest.
Итоги: селекторы HTML и CSS
Главное: DOM имеет древовидную структуру, а селекторы CSS позволяют перемещаться по ней. Используйте tag для указания типа элемента, .class — для класса, #id — для уникальных элементов, > — для прямых дочерних элементов, [attr] — для атрибутов. SelectorGadget и DevTools помогают находить селекторы в интерактивном режиме. XPath (//tag[@attr]) обрабатывает случаи, когда возможностей CSS недостаточно.
# Summary of key CSS selectors for web scraping:
# 'p' -> all <p> elements
# '.price' -> elements with class='price'
# '#main' -> element with id='main'
# 'div > p' -> direct child p of div
# 'a[href]' -> a elements that have href attr
# 'a[href*=http] -> a elements where href contains 'http'
# 'li:nth-child(2)' -> second li in its parent
# 'h1, h2' -> both h1 and h2 elements
# xpath='//td[@class="price"]' -> XPath alternative
library(rvest)
cat('Selectors are the foundation of reliable web scraping')Изучай R с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 43
- Уроки
- 159
Часто задаваемые вопросы
Урок «Структура HTML и селекторы CSS» бесплатный?
Да — полный текст урока «Структура HTML и селекторы CSS» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.
Чему я научусь в уроке «Структура HTML и селекторы CSS»?
Разберитесь в деревьях DOM и пишите селекторы CSS для выбора элементов. Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать R Academy?
Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Структура HTML и селекторы CSS»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке R Academy?
Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Структура HTML и селекторы CSS
- Основы html_element() и html_text()
- Скрейпинг таблиц и ссылок
- Обработка разбивки на страницы и нескольких страниц