
本文介绍使用 rvest 和 xml2 包,通过节点位置(而非属性选择器)可靠提取缺失 itemprop 或 aria-label 等标准语义标记的 html 文本内容,特别适用于结构稳定但语义标注不规范的房产类网页数据抓取。
本文介绍使用 rvest 和 xml2 包,通过节点位置(而非属性选择器)可靠提取缺失 itemprop 或 aria-label 等标准语义标记的 html 文本内容,特别适用于结构稳定但语义标注不规范的房产类网页数据抓取。
在网页爬虫实践中,常遇到 HTML 标签缺乏标准化语义属性(如 itemprop、data-* 或 class 命名不一致)的情况。例如,目标 <p> 标签中仅通过嵌套 <span> 的 aria-label 提供可读提示,但所需文本值实际位于 <p> 标签的直接文本节点(即 <span> 后的兄弟文本),而非 <span> 内容中——这导致 html_nodes("[aria-label='...']") %>% html_text() 返回空字符串。
此时,依赖DOM 结构稳定性比依赖属性更可靠。观察原始 HTML 可发现:<section class="card__amenities"> 下的 <p> 元素按固定顺序排列(面积 → 卧室数 → 浴室数 → 车位数),且车位信息恒为第 4 个 <p> 子节点(尽管其缺失 itemprop 属性)。因此,应转向基于位置的节点选取策略。
以下为完整、健壮的提取方案:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
library(rvest)
library(xml2)
library(dplyr)
# 读取 HTML(本地文件或 URL)
pagee <- read_html("html_file.html")
# 定位所有 amenities 区块(每个房源一个 section)
amenity_sections <- html_elements(pagee, "section.card__amenities")
# 初始化结果向量(预分配长度,提升性能)
garage_counts <- character(length(amenity_sections))
# 遍历每个 section,仅对子节点数 ≥ 4 的区块提取第 4 个 <p> 的纯文本
for (i in seq_along(amenity_sections)) {
p_nodes <- xml_children(amenity_sections[[i]]) # 获取所有直接子节点(含文本节点)
# 过滤出 <p> 元素(排除换行/空白文本节点)
p_elements <- p_nodes[xml_name(p_nodes) == "p"]
if (length(p_elements) >= 4) {
# 提取第 4 个 <p> 的全部文本(自动合并文本节点,去除前后空格)
garage_counts[i] <- html_text(p_elements[[4]], trim = TRUE)
} else {
garage_counts[i] <- NA_character_ # 缺失时标记为 NA
}
}
garage_counts
# 示例输出: [1] "2" NA "1" "2" ...关键要点与注意事项:
立即学习“前端免费学习笔记(深入)”;
- ✅ 优先验证结构稳定性:使用 html_structure(pagee) 或浏览器开发者工具检查目标页面是否始终维持 <p> 的顺序和层级关系。若顺序不固定(如车位有时排第 3),需改用更鲁棒的逻辑(如结合 aria-label 定位 <span>,再获取其父 <p> 的文本)。
- ⚠️ xml_child() vs xml_children():xml_child(node, 4) 直接获取第 4 个子节点(含文本节点),而 xml_children(node) 返回所有子元素节点(不含纯文本)。本例中因 <p> 内含 <span> + 文本,推荐先用 xml_children() 获取 <p> 列表,再对 <p> 调用 html_text() —— 更清晰且自动处理混合内容。
- ? 调试技巧:对单个 <p> 节点执行 xml_children(p_node) 查看内部节点构成,确认目标文本是否为独立文本节点(xml_name() == "#text")。
- ?️ 容错设计:务必检查子节点数量(length(p_elements) >= 4),避免因部分房源缺失车位信息导致索引越界错误。
- ? 进阶替代方案:若结构偶有变动,可结合正则匹配:html_text(p_node) %>% str_extract("\d+(?=\s*vagas?)"),但需确保页面文本模式统一。
该方法摆脱了对 HTML 语义标记完整性的依赖,转而利用前端渲染的视觉一致性,在真实爬虫项目中显著提升数据提取成功率。


















