You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用rlang::duplicate克隆rvest对象失效:修改副本仍变更原对象

问题成因

rvest底层依赖xml2库处理节点,xml2返回的HTML/XML节点对象本质是指向libxml2 C层结构体的外部指针,R层面的变量只是持有这个指针的引用,而非节点数据本身。
rlang::duplicate的作用是复制R层面的对象结构,但不会复制外部指针指向的底层C内存数据,所以你复制得到的x2和原x本质还是指向同一个底层节点,对x2的修改自然会同步到x上,该问题和R的惰性求值没有关系,是外部指针对象的特性导致的。

解决方案

不需要修改节点结构、不需要重新挂载子节点的前提下,有两种常用实现方案,全程不会改动原对象:

方案1:用Xpath直接提取节点自身文本

通过Xpath的text()语法直接匹配当前节点下的直属文本节点,忽略所有子元素节点:

# 直接提取目标节点的直属文本
self_text <- x |> 
  xml2::xml_find_all("./text()") |> 
  rvest::html_text() |> 
  paste(collapse = "")

# 输出结果和删除子节点后的结果一致
trimws(self_text)
#> [1] "text to extract"

方案2:筛选内容节点中的文本类型

通过xml_contents获取节点下所有直属内容,过滤出文本类型的节点后提取文本:

self_text <- x |> 
  xml2::xml_contents() |> 
  (\(content) content[xml2::xml_type(content) == "text"])() |> 
  xml2::xml_text() |> 
  paste(collapse = "")

内容的提问来源于stack exchange,提问作者geotheory

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 07:06:03