使用R删除具有更多嵌套页面的多个网页

使用R删除具有更多嵌套页面的多个网页,r,web-scraping,nested,rvest,R,Web Scraping,Nested,Rvest,我是一个新的R用户。我试图找到解决问题的办法,但就是找不到确切的办法,肯定是我的错。 无论如何:我有一个网站,我想把它刮下来放在一个.xlsx工作表上:http://www.tbca.net.br/base-dados/composicao_estatistica.php?pagina=1&atuald=1". 基本上,我对表格第一行所示的六个变量感兴趣:codigo、nome、nome inglés、ecc。对于数据集的所有53页。 这些变量中的任何一个都包含指向其他嵌套页面的链接,这些页面的

我是一个新的R用户。我试图找到解决问题的办法,但就是找不到确切的办法,肯定是我的错。 无论如何:我有一个网站,我想把它刮下来放在一个.xlsx工作表上:http://www.tbca.net.br/base-dados/composicao_estatistica.php?pagina=1&atuald=1". 基本上,我对表格第一行所示的六个变量感兴趣:codigo、nome、nome inglés、ecc。对于数据集的所有53页。 这些变量中的任何一个都包含指向其他嵌套页面的链接,这些页面的变量(componente、unidade、ecc)我也应该刮取,以便创建这样一个表:

codigo   nome  nome_inglés  nome_cientifico  grupo  marca  componente   unidade
C105      bla    blabla          blabla195    aq      awa    Energia      11    
C105      bla    blabla          blabla195    aq      awa    carboidrato  45
C105      bla    blabla          blabla195    aq      awa    proteina     22
C106      blu    blublu          blublu196    ar      owo    Energia      22    
C106      blu    blublu          blublu196    ar      owo    carboidrato  33
C106      blu    blublu          blublu196    ar      owo    proteina     44
然而,我做了各种尝试,但都没有成功

这是我的密码:

library(rvest)
library(dplyr)
library(data.table)
library(tidyverse)
library(stringr)

 get_tbca = function(tbca_link) {
 tbca_page = read_html(tbca_link)
 tbca_data = tbca_page %>% html_nodes("tr :nth-child(1)") %>%
html_text() 
 return(tbca_data)
  }


 tbca_df <- data.frame()

 lupin_fun <- function(page_result){

 print(paste("Page:", page_result))  

 link = paste0("http://www.tbca.net.br/base-dados/composicao_estatistica.php?pagina=", 
            page_result, "&atuald=1")
 page = read_html(link)

 codigo = page %>% html_nodes("td:nth-child(1) a") %>%  html_text()
 codigo_links <- page %>%  html_nodes("td:nth-child(1)") %>%
html_attr("href") %>% paste("http://www.tbca.net.br/base-dados/int_composicao_estatistica.php?cod_produto=", ., sep = "")
 nome = page %>%  html_nodes("td:nth-child(2) a") %>%  html_text()
 nome_ingles = page %>%   html_nodes("td:nth-child(3) a") %>%  html_text()
 nome_cientifico = page %>%  html_nodes("td:nth-child(4) a") %>%  html_text()
 grupo = page %>%  html_nodes("td:nth-child(5) a") %>%  html_text()
 marca = page %>%  html_nodes("td:nth-child(6) a") %>%  html_text()
 tbca_reference = sapply(codigo_links, FUN = get_tbca, USE.NAMES = FALSE)

 tbca_df <- cbind(tbca_reference, codigo, nome, nome_ingles, nome_cientifico, grupo, marca, stringsAsFactors = FALSE)

 return(tbca_df)  
 }


 lupin_list <- lapply(1:3, lupin_fun)

 lupin_result <- do.call(rbind, lupin_list)
库(rvest)
图书馆(dplyr)
库(数据表)
图书馆(tidyverse)
图书馆(stringr)
get\u tbca=函数(tbca\u链接){
tbca_页面=读取html(tbca_链接)
tbca_数据=tbca_页面%>%html_节点(“tr:nth child(1)”)%%>%
html_text()
返回(待定数据)
}
tbca_df%html_text()
codigo_链接%html_节点(“td:n子节点(1)”)%>%
html_属性(“href”)%%>%粘贴http://www.tbca.net.br/base-dados/int_composicao_estatistica.php?cod_produto=“,,sep=”“)
nome=page%%>%html\u节点(“td:nth-child(2)a”)%%>%html\u文本()
nome\u ingles=page%>%html\u节点(“td:n子(3)a”)%>%html\u文本()
nome_cientifico=page%>%html_节点(“td:nth子(4)a”)%>%html_文本()
grupo=page%>%html\u节点(“td:nth-child(5)a”)%>%html\u文本()
marca=page%>%html\u节点(“td:nth-child(6)a”)%>%html\u文本()
tbca_reference=sapply(codigo_链接,FUN=get_tbca,USE.NAMES=FALSE)

tbca_df我认为你的思路是对的。我可以看到两个问题:

  • 我认为在这种情况下使用
    html\u表
    要容易得多。您直接将表作为数据帧获取,而不是获取单元格/列,然后将所有内容绑定在一起
  • 如果我发现的问题在
    codigo\u链接中
    。在提取
    href
    属性之前,需要在每个
    中获取带有
    标记的节点。我在解决方案中修复了这一部分
  • 我就是这样做的:

    library(rvest)
    library(dplyr)
    
    get.table.in.link <- function(url1) {
      # get code of food from link
      cod_produto <- strsplit(url1, 'cod_produto=')[[1]][2]
    
      # get table in nested link 
      table.2 <- read_html(url1) %>% html_table() %>% .[[1]]
    
      table.3 <- table.2 %>% 
        # filter only Energia, carboidrato, proteina (if you want all rows you can ignore this)
        dplyr::filter(Componente %in% c('Energia', 'Carboidrato total', 'Proteína')) %>%
        # Also choosing subset of columns (you can also change this)
        dplyr::select(Componente, Unidades, `Valor por 100 g`) %>%
        # add column with product code
        dplyr::mutate(Código=cod_produto) %>%
        # change decimal separator and convert to numeric
        dplyr::mutate(`Valor por 100 g`= as.numeric(gsub(',','.',gsub('\\.', '', `Valor por 100 g`))))
      
      return(table.3)
    }
    
    get.main.table <- function(page.number) {
      print(paste("Page:", page.number))
      
      url.main <- paste0("http://www.tbca.net.br/base-dados/composicao_estatistica.php?pagina=", page.number, "&atuald=1")
     
      page <- read_html(url.main)
      
      # this is simpler to get the main table
      df.table <- page %>% html_table() %>% .[[1]]
      
      # now get list of links in each row (get from first column)
      list.links <- page %>%  html_nodes("td:nth-child(1)") %>% html_nodes('a') %>%
        html_attr("href") %>% paste("http://www.tbca.net.br/base-dados/", ., sep = "")
      
      # get table with details of each product
      # ldply applies function for each element of list.links, then combine results into a data frame
      table.composicao <- plyr::ldply(list.links, get.table.in.link)
      
      # now merge df.table and table.composicao using "Código"   
      df.final <- df.table %>% left_join(table.composicao, by="Código")  
      
      return(df.final)
    }
    
    # run get.main.table with arguments = 1, 2, 3 and combine results in a dataframe
    df.total <- plyr::ldply(1:3, get.main.table)
    
    库(rvest)
    图书馆(dplyr)
    get.table.in.link%
    #还可以选择列的子集(您也可以对此进行更改)
    dplyr::选择(组件,大学,`Valor por 100 g`)%>%
    #添加带有产品代码的列
    dplyr::突变(Código=cod_produto)%>%
    #更改小数分隔符并转换为数字
    dplyr::mutate(`Valor por 100 g`=as.numeric(gsub('','','.','.',gsub('\\.','',Valor por 100 g`)))
    回报(表3)
    }
    get.main.table%
    html_属性(“href”)%%>%粘贴http://www.tbca.net.br/base-dados/“,,sep=”“)
    #获取每个产品的详细信息表
    #ldply为list.links的每个元素应用函数,然后将结果合并到数据帧中
    
    table.composicao,工作完美,非常有意义!谢谢