标签的 HTML 表格并智能拆分列
" />
本文介绍如何使用 rvest 和 tidyr 在网页抓取后,精准处理 HTML 表格中由 分隔的复合文本(如“机构名地址”),将其自动拆分为两个独立列,避免手动解析 DOM 或正则误匹配。
本文介绍如何使用 `rvest` 和 `tidyr` 在网页抓取后,精准处理 html 表格中由 `
` 分隔的复合文本(如“机构名
地址”),将其自动拆分为两个独立列,避免手动解析 dom 或正则误匹配。
在使用 rvest::html_table() 解析网页表格时,一个常见痛点是:当某列单元格内嵌 <br> 标签(例如 <td>LMS - City 1, 2, 3 YSA<br><small>612 Glen Rd</small>
</td>)时,html_table() 会直接忽略 HTML 结构,将换行标签连同文本一并抹平为 "LMS - City 1, 2, 3 YSA612 Glen Rd",导致关键信息混杂、无法结构化使用。
标准解决方案并非重写 HTML 解析逻辑,而是在 html_table() 执行前对原始 HTML 文本进行轻量预处理——将 <br> 替换为一个安全、唯一、非 HTML 的占位符(如 "{-br-}"),再交由 html_table() 解析;最后用 tidyr::separate_wider_delim() 按该占位符精准切分列。该方法兼顾鲁棒性与简洁性,无需遍历节点或提取 text_content() + 正则匹配,也规避了 <br> 出现在其他列(如备注)时的误拆风险。
以下是集成到原爬虫流程中的核心增强代码(替换原循环中 html_table() 部分):
library(rvest)
library(stringr)
library(tidyr)
# 在 for 循环内部,替换原 table <- ... html_table() 部分:
page <- session %>% jump_to(page_url)
content_text <- httr::content(page$response, as = "text")
# 关键预处理:将 <br> 替换为唯一分隔符(注意:fixed() 确保字面匹配)
cleaned_html <- str_replace_all(content_text, fixed("<br>"), "{-br-}")
# 解析表格(此时 <br> 已被转义,不再干扰解析)
table_df <- read_html(cleaned_html) %>%
html_element("table") %>%
html_table(fill = TRUE)
# 对 Location 列按占位符拆分为 Location 和 Address 两列
# 注意:列名需与实际解析结果一致(此处假设原始表头为 "Location")
table_df <- table_df %>%
separate_wider_delim(
cols = Location,
delim = "{-br-}",
names = c("Location", "Address"),
too_few = "align_start", # 若某行无 <br>,右侧补 NA
too_many = "error"
)✅ 注意事项与最佳实践:
立即学习“前端免费学习笔记(深入)”;
-
占位符选择原则:必须确保不与真实业务数据冲突(如
{--br--}或|BR|更稳妥),避免sep=","类型误切;fixed()匹配可杜绝正则元字符干扰。 -
列名一致性:
separate_wider_delim()的cols参数需严格匹配html_table()输出的列名(可通过names(table_df)核对,原始 HTML 表头可能生成如"LocationLocation"的重复名,需先rename()规范)。 -
性能优化建议:原代码中
all_tables 属于「R Inferno 第二圆」反模式(动态增长对象)。应预先分配列表:<code>all_tables ,再用 <code>all_tables[[i]] 赋值,大幅提升大表合并效率。 -
容错增强:若部分行无
<br>(如纯名称),设置too_few = "align_start"可使"Location"保留原值,"Address"自动填充NA,保障数据完整性。
通过这一预处理+结构化拆分策略,您既能复用 rvest 的成熟表格解析能力,又能精准解耦混合语义字段,最终输出清晰、可直接用于分析或导出的规范化数据框。



















