我想从一个html文件中提取键-值对(参见下面的示例).遗憾的是,没有与每个键-值对对应的html node (如div元素).相反,所有信息都出现在一个段落中,其中关键点突出显示为<strong>.

我想将键值对表示为一个嵌套框的两列或两个相同长度的列表,其中key 1对应于value 1key 2value 2avalue 2b,以及key 3value 3.文件中的换行符设置不一致.

因为每一对都没有div元素,所以我可能不得不想出一个策略来在每个键之后的段落后面加上split?我在下面附上一个将html视为原始文本的黑客try :

library(tidyverse)
library(rvest)

html <- minimal_html(
  "<p>
    <strong>key 1</strong> value 1
    <br></br>
    <strong>key 2</strong> value 2a
    <br></br>
    value 2b
    <br></br>
    <strong>key 3</strong> 
    <br></br>
    value 3
  </p>"
)

# hacky solution treating html as raw text
s <- html |> 
  html_elements("p") |> 
  as.character()

parse_html <- function(s) {
  s |> 
    read_html() |> 
    html_text2()
}

s |> 
  str_replace_all("<strong>(.*)</strong>", "✂️\\1🔧") |> 
  str_split_1("✂️") |> 
  map_chr(parse_html) |> 
  discard(\(x) str_length(x) == 0L) |> 
  str_split("🔧") |> 
  map(str_squish)
#> [[1]]
#> [1] "key 1"   "value 1"
#> 
#> [[2]]
#> [1] "key 2"             "value 2a value 2b"
#> 
#> [[3]]
#> [1] "key 3"   "value 3"

创建于2024-01-18年第reprex v2.1.0

推荐答案

与使用css Select 器相比,使用XPath可以更进一步,虽然下面的示例似乎处理了包含的html片段,但我相信有更健壮、更优雅的XPath策略来实现同样的目标.

我们可以从values开始,从.//p/strong/following-sibling::text()开始,我们可以得到strong个元素之后的所有文本 node (values),只有空格的字符串就可以了,因为我们可以稍后过滤掉这些字符串.在迭代该 node 集时,我们现在可以 for each 具有./preceding-sibling::strong[1]的文本 node 获得最接近的前strong个元素(key).

library(tidyverse)
library(rvest)

html <- minimal_html(
  "<p>
    <strong>key 1</strong> value 1
    <br></br>
    <strong>key 2</strong> value 2a
    <br></br>
    value 2b
    <br></br>
    <strong>key 3</strong> 
    <br></br>
    value 3
  </p>"
)

preceding_key_text <- function(value_node){
  html_element(value_node, xpath = "./preceding-sibling::strong[1]") |> 
    html_text(trim = TRUE)
}

html |>
  html_elements(xpath = ".//p/strong/following-sibling::text()") |> 
  map(\(value_) list(
    key = preceding_key_text(value_),
    value = html_text(value_, trim = TRUE)
    )) |>
  discard(\(x) x[["value"]] == "") |>
  bind_rows()

结果:

#> # A tibble: 4 × 2
#>   key   value   
#>   <chr> <chr>   
#> 1 key 1 value 1 
#> 2 key 2 value 2a
#> 3 key 2 value 2b
#> 4 key 3 value 3

创建于2024-01-19年第reprex v2.0.2

R相关问答推荐

单击 map 后,将坐标复制到剪贴板

从嵌套列表中智能提取线性模型系数

查找图下的面积

随机森林回归:下拉列重要性

如果行和大于值,则过滤

使用Facet_WRAP时更改框图中线的 colored颜色

有效识别长载体中的高/低命中

从服务器在Shiny中一起渲染图标和文本

R -使用矩阵reshape 列表

在不对R中的变量分组的情况下取两行的平均值

使用列中的值来调用函数调用中应使用的其他列

数值型数据与字符混合时如何进行绑定

用多边形替换地块点

在使用SliderInput In Shiny(R)设置输入数据的子集时,保留一些情节痕迹

R将函数参数传递给ggploy

根据排名的顶点属性调整曲线图布局(&Q)

从矩阵创建系数图

将y轴格式更改为R中的百分比

使用相对风险回归计算RR

臭虫?GradeThis::grade_this_code()在`-code-check`块中失败