如何在一列中保存倍数匹配? rvest、R 和 stringr

How to save multiples match in one column? rvest, R and stringr

这道题是问题的序曲

我有这两个例子html:url1.html ; url2.html

url3.html是另一个IPC多的例子

URL2.html 中没有信息 (51) 而 URL1.html 中有。

我在 R 中使用此代码:

library(rvest)
library(tidyverse)
library(stringr)

x<-data.frame(
    URL=c(1:2),
    page=c(paste(readLines("url1.html"), collapse="\n"),
                 paste(readLines("url2.html"), collapse="\n"))
) 

for (i in 1:nrow(x)){
    html<-x$page[i]%>% unclass() %>% unlist()
    read_html(html,encoding = "ISO-8859-1") %>% 
        rvest::html_elements(xpath = '//*[@id="principal"]/table[2]') %>%
        html_nodes(xpath='//div[@id="classificacao0"]') %>%  
        html_text(trim=T)%>%  
        str_replace_all(.,"[\n\r\t]+", "")%>%
        stringr::str_trim( ) -> tmp
    
    if(length(tmp) == 0) tmp <- "ND"
    x$ipc_0[i] <- tmp %>% str_replace_all(.,"\s+", " ") %>% str_replace_all(.," \)", "\)")
}

for (i in 1:nrow(htm_temp)){
    html<-x$page[i]%>% unclass() %>% unlist()
    read_html(html,encoding = "ISO-8859-1") %>% 
        rvest::html_elements(xpath = '//*[@id="principal"]/table[2]') %>%
        html_nodes(xpath='//div[@id="classificacao1"]') %>%  
        html_text(trim=T)%>%  
        str_replace_all(.,"[\n\r\t]+", "")%>%
        stringr::str_trim( ) -> tmp
    
    if(length(tmp) == 0) tmp <- "ND"
    x$ipc_1[i] <- tmp %>% str_replace_all(.,"\s+", " ") %>% str_replace_all(.," \)", "\)")
}

结果:部分正确

需要result:create具有以下结构的新数据框。

URL IPC
1 B62B 1/16 (1968.09)...
1 B62B 1/00 (1968.09)...
2 ND

问题:url 有代码 (51) 而其他没有。当您拥有代码 (51) 时,该结构可以包含具有以下结构的“n”id xpath='//div[@id="classificacao0"]。 Rating Id 可以包含从 0 到“n”的值。如何优化此代码以捕获必要的信息,而不必为每个“n”做大量的 for(向量中的变量)?

知道如何解决这个问题吗?

您可以使用 css attribute = value css 选择器列表,其中 ^ 以运算符开头到 capture/exclude 具有特定 id 和 id 值的元素。

将您当前的提取代码转换为接受(在本例中)url 作为参数的函数。扩展正则表达式以删除未在所需输出中显示的其他字符。

具有该功能 return url 和 ipc 的小标题;将整个事情包装在 map_dfr() 调用中以生成单个 DataFrame 结果。

library(rvest)
library(tidyverse)

urls <- sprintf("https://prequest.websiteseguro.com/example/url%i.html", 1:3)

get_ipc <- function(url) {
  ipc <- read_html(url, encoding = "ISO-8859-1") %>%
    html_elements("div[id^=classificacao]:not([id^=classificacaoc]) .normal > b") %>%
    html_text(trim = T) %>% 
    str_replace_all(.,  "[\n\r\t]+|\(|\s{2,}|\)", "")%>%
    stringr::str_trim()
    if(length(ipc) == 0) ipc <- "ND"
    return(tibble(url = url, ipc))
}

df <- purrr::map_dfr(urls, get_ipc)
print(df)