rvest - Соскоб таблицы - PullRequest
       30

rvest - Соскоб таблицы

0 голосов
/ 28 февраля 2019

Я очищаю веб-страницу с помощью библиотеки 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 для преобразования в фрейм данных и затем применяю уникальное для получения соответствующих данных.

Есть ли способ, с помощью которого я могу извлечь все данные из таблицы, не углубляясь один за другим.

1 Ответ

0 голосов
/ 28 февраля 2019

Когда вы смотрите на необработанный список 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
...