HTML 结构与 CSS 选择器
了解 DOM 树,并编写 CSS 选择器来定位元素
HTML 结构与 CSS 选择器 是 CoddyKit 上的免费 R Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 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 会选择 div 内任意层级的 p。div > p 只选择直接子元素。h1 + p 会选择紧跟在 h1 后面的 p(相邻兄弟元素)。
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 会选择类为 card 的 div 内的 h2。逗号用于分隔多个相互独立的选择器: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。右键点击任意元素,选择检查,元素面板就会显示 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)快速检查
测试您对使用 rvest 进行网页抓取时所用 CSS 选择器的理解。
回顾:HTML 与 CSS 选择器
要点: DOM 是一棵树;CSS 选择器用于在其中导航。使用 tag 指定元素类型,使用 .class 指定类,使用 #id 指定唯一元素,使用 > 指定直接子元素,使用 [attr] 指定属性。SelectorGadget 和 DevTools 可帮助您通过交互方式查找选择器。在 CSS 无法满足需求时,可以使用 XPath(//tag[@attr])。
# 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')常见问题解答
「HTML 结构与 CSS 选择器」课时是免费的吗?
是的 — 「HTML 结构与 CSS 选择器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。
「HTML 结构与 CSS 选择器」这节课中我会学到什么?
了解 DOM 树,并编写 CSS 选择器来定位元素 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 R Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「HTML 结构与 CSS 选择器」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 R Academy 课中编写并运行代码吗?
能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- HTML 结构与 CSS 选择器
- html_element() 与 html_text() 基础
- 抓取表格与链接
- 处理分页与多页面