0Pricing
R Academy · 课时

html_element() 与 html_text() 基础

从抓取的页面中提取文本、属性和表格数据

html_element() 与 html_text() 基础 是 CoddyKit 上的免费 R Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。

read_html():加载页面

read_html() 是 rvest 的入口函数。您可以传入 URL 或原始 HTML 字符串。它会返回一个 xml_document 对象,表示解析后的 DOM 树,可直接用于查询。

library(rvest)

# From a URL (requires internet connection)
# page <- read_html('https://books.toscrape.com')

# From a raw HTML string (great for testing)
page <- read_html('
  <html><body>
    <h1>Book Store</h1>
    <p class="desc">Over 1000 books!</p>
  </body></html>
')
class(page)  # 'xml_document' 'xml_node'

html_element() 与 html_elements()

html_element() 返回第一个匹配的节点(如果没有找到则返回 NA)。html_elements() 将所有匹配的节点以列表形式返回。预期只有一个结果时使用单数形式,抓取列表时使用复数形式。

library(rvest)
page <- read_html('
  <ul>
    <li class="item">Apple</li>
    <li class="item">Banana</li>
    <li class="item">Cherry</li>
  </ul>
')
# Singular: gets first match
first_item <- html_element(page, '.item')
html_text2(first_item)  # 'Apple'

# Plural: gets all matches
all_items <- html_elements(page, '.item')
html_text2(all_items)  # c('Apple', 'Banana', 'Cherry')
length(all_items)  # 3

使用 html_text2() 获取干净文本

html_text2() 从节点中提取文本内容,去除 HTML 标签并整洁地合并空白字符。它会将 <br> 处理为换行符。较旧的 html_text() 对空白字符的处理不够智能。

library(rvest)
page <- read_html('
  <div class="product">
    <h2>  Laptop  </h2>
    <p>Price: <strong>$999</strong></p>
    <p>  Free   shipping  </p>
  </div>
')
# html_text2 trims whitespace intelligently
title <- html_element(page, 'h2')
html_text2(title)  # 'Laptop' (no extra spaces)

# From the whole div - collapses nested text
div <- html_element(page, '.product')
html_text2(div)  # 'Laptop\nPrice: $999\nFree shipping'

html_attr():提取属性

html_attr(node, 'attr_name') 提取 HTML 属性的值。这对于从链接中获取 href、从图像中获取 src、获取 data-* 属性等操作至关重要。

library(rvest)
page <- read_html('
  <div>
    <a href="https://example.com" title="Example site">Visit</a>
    <img src="/images/photo.jpg" alt="A photo">
    <div data-price="29.99">Product</div>
  </div>
')
# Extract href from link
link <- html_element(page, 'a')
html_attr(link, 'href')  # 'https://example.com'
html_attr(link, 'title')  # 'Example site'

# Extract src from image
img <- html_element(page, 'img')
html_attr(img, 'src')  # '/images/photo.jpg'

# Extract data attributes
div <- html_element(page, 'div[data-price]')
html_attr(div, 'data-price')  # '29.99'

html_attrs():所有属性

html_attrs(node) 返回节点所有属性组成的具名字符向量。节点属性名称未知,或您想检查元素上有哪些可用属性时,这一函数非常有用。

library(rvest)
page <- read_html('
  <a href="/page" class="nav-link" id="home" data-section="main">Home</a>
')
link <- html_element(page, 'a')

# Get all attributes at once
attrs <- html_attrs(link)
attrs
# href        class        id           data-section
# '/page'     'nav-link'   'home'       'main'

# Access by name
attrs['href']   # '/page'
attrs['class']  # 'nav-link'
names(attrs)    # all attribute names

html_children():子节点

html_children(node) 返回元素的直接子节点。结合 html_name() 获取标签名称后,它对于以编程方式了解页面结构非常有用。

library(rvest)
page <- read_html('
  <nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
    <span>|</span>
    <a href="/contact">Contact</a>
  </nav>
')
nav <- html_element(page, 'nav')

# Get all direct children
kids <- html_children(nav)
length(kids)  # 4

# Get tag names of children
html_name(kids)  # c('a', 'a', 'span', 'a')

# Filter to only anchor children
links <- kids[html_name(kids) == 'a']
html_text2(links)  # c('Home', 'About', 'Contact')

html_name():标签名称

html_name(node) 以小写字符串形式返回节点的标签名称(例如 'div'、'p'、'a')。获取节点列表后,可以使用它按元素类型进行筛选。

library(rvest)
page <- read_html('
  <article>
    <h2>Title</h2>
    <p>First paragraph.</p>
    <img src="img.jpg">
    <p>Second paragraph.</p>
  </article>
')
article <- html_element(page, 'article')
all_children <- html_children(article)

# Check tag name of each child
html_name(all_children)
# c('h2', 'p', 'img', 'p')

# Get only paragraph children
paras <- all_children[html_name(all_children) == 'p']
html_text2(paras)
# c('First paragraph.', 'Second paragraph.')

串联选择

您可以将节点(而不仅是文档)作为 html_element() 的第一个参数传入。这样会将搜索范围限定在该节点内部,这对于抓取产品卡片或表格行等重复结构至关重要。

library(rvest)
page <- read_html('
  <div class="card">
    <h3>Laptop</h3>
    <span class="price">$999</span>
  </div>
  <div class="card">
    <h3>Phone</h3>
    <span class="price">$499</span>
  </div>
')
# Get all cards, then extract fields from each
cards <- html_elements(page, '.card')

names_list <- html_text2(html_elements(page, '.card h3'))
prices_list <- html_text2(html_elements(page, '.card .price'))

data.frame(name = names_list, price = prices_list)

对 NodeSet 使用 html_attr

对 节点集(html_elements() 的结果)调用时,html_attr() 会返回一个属性值向量,每个节点对应一个值。缺失的属性会返回 NA。

library(rvest)
page <- read_html('
  <ul>
    <li><a href="/page1">Page 1</a></li>
    <li><a href="/page2">Page 2</a></li>
    <li><span>No link</span></li>
    <li><a href="/page3">Page 3</a></li>
  </ul>
')
# Get all a elements
links <- html_elements(page, 'a')

# html_attr on a nodeset returns a vector
hrefs <- html_attr(links, 'href')
hrefs  # c('/page1', '/page2', '/page3')

# Link text alongside hrefs
texts <- html_text2(links)
data.frame(text = texts, href = hrefs)

处理缺失元素

没有任何匹配项时,html_element() 会返回 NA 节点,而不是 NULL。对 NA 节点调用 html_text2() 会返回 NA_character_。元素可能缺失时,请始终检查结果中的 NA。

library(rvest)
page <- read_html('
  <div class="product">
    <h3>Widget</h3>
    <!-- No price tag here -->
  </div>
')
# Element exists
title <- html_element(page, 'h3')
html_text2(title)  # 'Widget'

# Element does NOT exist -> NA node
price <- html_element(page, '.price')
html_text2(price)  # NA
is.na(html_text2(price))  # TRUE

# Safe extraction with default
price_text <- html_text2(price)
if (is.na(price_text)) price_text <- 'N/A'
price_text  # 'N/A'

综合应用

结合使用 html_elements()、html_text2() 和 html_attr(),将结构化数据抓取到数据框中,这是使用 rvest 进行网页抓取的典型最终目标。

library(rvest)
page <- read_html('
  <div class="book">
    <a href="/book/1" class="title">R Programming</a>
    <span class="author">Hadley Wickham</span>
    <span class="rating" data-stars="5">*****</span>
  </div>
  <div class="book">
    <a href="/book/2" class="title">Advanced R</a>
    <span class="author">Hadley Wickham</span>
    <span class="rating" data-stars="5">*****</span>
  </div>
')
titles  <- html_text2(html_elements(page, '.title'))
authors <- html_text2(html_elements(page, '.author'))
links   <- html_attr(html_elements(page, 'a.title'), 'href')
ratings <- html_attr(html_elements(page, '.rating'), 'data-stars')
data.frame(title=titles, author=authors, link=links, stars=ratings)

快速检查

测试您对用于浏览 HTML 文档的 rvest 核心函数的了解。

回顾:rvest 核心函数

要点: read_html() 加载页面;html_element() 获取第一个匹配项;html_elements() 获取所有匹配项。使用 html_text2() 提取文本,使用 html_attr() 提取属性,使用 html_children() 获取子节点,使用 html_name() 获取标签名称。缺失元素会返回 NA 节点——在生产环境的抓取程序中,请始终处理 NA。

library(rvest)
# Core rvest workflow:
# 1. Load page
# page <- read_html(url)

# 2. Find elements
# node  <- html_element(page, 'css-selector')
# nodes <- html_elements(page, 'css-selector')

# 3. Extract content
# html_text2(node)        -> text content
# html_attr(node, 'href') -> attribute value
# html_attrs(node)        -> all attributes
# html_name(node)         -> tag name
# html_children(node)     -> child nodes

# 4. Build data frame
# data.frame(title = html_text2(...), link = html_attr(...))
cat('rvest follows the tidy data philosophy')

常见问题解答

「html_element() 与 html_text() 基础」课时是免费的吗?

是的 — 「html_element() 与 html_text() 基础」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。

「html_element() 与 html_text() 基础」这节课中我会学到什么?

从抓取的页面中提取文本、属性和表格数据 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「html_element() 与 html_text() 基础」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 R Academy 课中编写并运行代码吗?

能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. HTML 结构与 CSS 选择器
  2. html_element() 与 html_text() 基础
  3. 抓取表格与链接
  4. 处理分页与多页面
← 返回 R Academy