rvest-抓取表格

时间:2019-02-28 09:46:21

标签: r web-scraping html-table rvest

我正在使用rvest库抓取网页,我的兴趣是从网页中存在的表中提取所有数据。

library(rvest)
library(tidyr)

url <- ''

# Parsing the HTML Code from Website
hdb_webpage <- read_html(url)

## Grabbing Page Info - Table Input 1
dat_1 <- hdb_webpage %>%
  html_table(header=FALSE) %>% 
  .[[2]] %>%
  as.data.frame()
# Transposing
dat_1 <- as.data.frame(t(dat_1$X3))
# Changing colnames
colnames(dat_1) <- c("Name", "Address", "Category", "TradeType", "Contact")

我将继续手动执行列表中其余数据框的相同操作。列表中实际上存在18个数据框,其中包含变化的变量和观察值,这导致花费大量时间清理数据。

或者,为了抓取整个表,我使用以下代码;

tbls_ls <- hdb_webpage %>%
  html_nodes("table") %>%
  html_table(header = FALSE) %>%
  .[2:18]

df <- data.frame(matrix(unlist(tbls_ls), nrow=279, byrow=T),stringsAsFactors=FALSE)

df <- unique(df)

此代码将表中的所有信息提取到列表中,然后使用 unlist 转换为数据框,然后应用 unique 来获取相关数据。

有没有一种方法可以使我从表中提取所有数据而无需一一列举。

1 个答案:

答案 0 :(得分:0)

当您查看从rw.list读入的原始列表html_table()时,有三种if情况需要不同的处理。

library(rvest)

path <- 'https://services2.hdb.gov.sg/webapp/AA16RMSBusinessDirectory/AA16SLevelmap?SearchOption=1&BLK=166&STREET=WOODLANDS+STREET+13++++++++++++++++++++++++++++++++++++++++++++++++++%EF%BF%BD&pcode=730166&STREETLIST=--&MAIN_TRADE_CODE=0000Please+Select+Category%24&Forward=&FROMHOME=true&Slvl=1&SEARCHPANEL=1&MAIN_TRADE_DESC'

# Parsing the HTML Code from Website
rw <- read_html(path)
rw.list <- html_table(rw)[-1]
names(rw.list) <- lapply(rw.list, function(x)  # attribute clean names
  unique(gsub("\\n|\\r|\\t|\\s+(More Information)?", "", x[1, ])))

l1 <- lapply(rw.list, function(x) t(x[-(1:2), ]))

l1 <- lapply(1:length(l1), function(x) {
  d <- as.data.frame(l[[x]], stringsAsFactors=FALSE)
  names(d) <- d[1, ]
  if (length(d) == 10 | length(d) == 6)
    out <- matrix(unlist(d[3, grep("Category|Trade|(Tel No)", names(d), )]), 
                  ncol=2,
                  dimnames=list(NULL, d[1, 1:2]))
  else if (length(d) == 8)
    out <- matrix(unlist(t(d[3, grep("Category|Trade|(Tel No)", names(d), )])), 
                  ncol=3, byrow=TRUE, dimnames=list(NULL, d[1, 1:3]))
  else
    out <- d[3, ]
  return(cbind(id=names(l)[x], out))
})

我们可以与Reduce()合并的清除列表。

result <- Reduce(function(...) merge(..., all=TRUE), l1)

结果

head(result, 3)
#                        id Category                                             Trade   Tel No
# 1   1.GREENEMERALDAQUARIA     Pets Aquarium Fish (freshwater/marine) And Accessories 68160208
# 2         2.SEEMRALICIOUS   Beauty                                      Beauty Salon 66357994
# 3 3.MORRISONOPTICALPTELTD Shopping                           Optical Goods & Eyewear 63666300