如何在通用函数中包装 css 和 html_nodes 中的 xpath 参数

How to wrap css and xpath arguments in html_nodes in a generic function

我想围绕 html_node 创建一个能够读取 CSS 和 XPATH 参数的包装器。我想创建一个引用表达式,可以提供给 html_node 并在现场进行评估。我想出了如何分别为 css 和 xpath 创建路径参数,但是当我将此表达式提供给 html_node 时它不起作用。为什么不呢?

page_parser <- function(dat_list, path = NULL, css = FALSE, attr = "") {
  library(rlang)
  # make css or path argument for html_nodes
  if (css == TRUE) {
    path <- expr(`=`(css, !!path))
  }else{
    path <- expr(`=`(xpath, !!path))
  }
  # extract attribute value
  map(dat_list, possibly(function(x) { html_nodes(x, !!path) %>% html_attr(attr) %>% extract(1)}, NA)) %>% 
     map(1) %>% 
     lapply(function(x) ifelse(is_null(x), "", x)) %>%
     unlist()
 }

read_html("https://www.freitag.de/autoren/lutz-herden/alexis-tsipras-fall-oder-praezedenzfall" %>% parge_parser(path = "//meta[@property='og:title']")

read_html("https://www.freitag.de/autoren/lutz-herden/alexis-tsipras-fall-oder-praezedenzfall" %>% parge_parser(path = ".title", css = TRUE)

无论我指定的是CSS还是Xpath,函数都应该吐出css或xpath后面的内容。

最好的, 莫里茨

一般来说,!!运算符只在支持quasiquoation的函数中有效。不幸的是,rvest::html_nodes 目前没有。 (但由于它是 tidyverse 的一部分,如果以后添加支持,我不会感到惊讶。)

有几种方法可以通过编程方式为函数调用提供参数,包括来自 base R 的 do.call()。但是,如果您使用 map 遍历页面,我建议预先通过 purrr::partial():

设置 html_nodescssxpath 参数
page_parser <- function(dat_list, path = NULL, css = FALSE, attr = "") {
  # make css or xpath argument for html_nodes
  if (css == TRUE) {
    f_html_nodes <- purrr::partial( html_nodes, css = path )
  }else{
    f_html_nodes <- purrr::partial( html_nodes, xpath = path )
  }

  # extract attribute value
  map(dat_list, possibly(function(x) { f_html_nodes(x) %>% html_attr(attr) %>% 
                                         extract(1)}, NA)) %>% 
                  map(1) %>% lapply(function(x) ifelse(is_null(x), "", x)) %>%
    unlist()
}