Очистка веб-страниц с помощью R: на веб-сайте есть два раскрывающихся меню - PullRequest
2 голосов
/ 30 мая 2020

Я хочу получить данные оценки со следующего веб-сайта, используя R для функции l oop: https://www7.nau.edu/pair/reports/ClassDistribution

Чтобы получить данные таблицы I сначала нужно выбрать год, а затем школу Academy c. Мне нужны данные за 2015-2019 годы и для всех школ (A CC, ACM, ..., WGS) в университете. Когда я выбираю год и школу, URL-адрес не меняется, поэтому я не получаю табличных данных. Буду очень признателен за вашу помощь и совет. Я могу создать для l oop, мне просто нужно посмотреть, как вытащить первую таблицу.

Я использовал следующий код для веб-сайта stati c:

library(XML)
library(RCurl)
url <- "https://www7.nau.edu/pair/reports/ClassDistribution"
url.parsed <- htmlParse(getURL(url), asText = TRUE)
tableNodes <- getNodeSet(url.parsed, '//*[@id="pp_table"]/table')
grade_data <- readHTMLTable(tableNodes[[1]], header=F, stringsAsFactors=F)

Ответы [ 2 ]

3 голосов
/ 30 мая 2020

Вот решение, использующее RSelenium.

library(RSelenium)

rD <- rsDriver(browser = c("firefox")) #specify browser type you want Selenium to open
remDr <- rD$client
remDr$navigate("https://www7.nau.edu/pair/reports/ClassDistribution") # navigates to webpage


# select first dropdown list
option <- remDr$findElement(using='id', value="MainContent_TermList")

#get all option values from dropdown list
option_values <- option$getPageSource()[[1]] %>% 
  str_extract_all("1[0-9]{3}")

#select second dropdown list
option2 <- remDr$findElement(using='id', value="MainContent_SubjectList")

#get all option values from dropdown list
option_values_2 <- option2$getElementText() %>% 
  str_split("\\n") %>% 
  unlist()

#### create loop to loop over all tables...


option <- remDr$findElement(using='id', value="MainContent_TermList")

option <- remDr$findElement(using = 'xpath', "//*/option[@value = '1194']") #change '1194' to values in option_values in loop
option$clickElement()

# change dropdown selection
option2 <- remDr$findElement(using='id', value="MainContent_SubjectList")
option2 <- remDr$findElement(using = 'xpath', "//*/option[@value = 'AHB']") #change 'AHB' to values in option_values_2 in loop
option2$clickElement()

# click submit
submit <- remDr$findElement(using='id', value="MainContent_Button1")
submit$clickElement()


#get table
tb <- remDr$findElement(using='id', value="MainContent_GridView1")

tb$getPageSource()[[1]] %>% 
  read_html() %>% 
  html_table(fill = TRUE)

Теперь вам просто нужно l oop больше option_values и option_values2, чтобы получить таблицы.

2 голосов
/ 30 мая 2020

Вы имеете дело с простой формой, которую нужно обновлять и отправлять для каждого семестра и каждого предмета. Селен - это хорошо, но я думаю, что здесь его может быть слишком много. rvest::html_session хорош в таких вещах:

library(tidyverse)
library(rvest)

# Start session, extract semesters from form and filter.
session <- html_session("https://www7.nau.edu/pair/reports/ClassDistribution")
form <- html_form(session)[[1]]
semesters <- form$fields[[5]]$options[-1]
semesters <- semesters[grep("201[5-9]", names(semesters))]

# Update form with semester info, submit, and extract subjects.
form <- set_values(form, 'ctl00$MainContent$TermList' = semesters[1])
session <- submit_form(session, form, "<unnamed>")
form <- html_form(session)[[1]]
subjects <- form$fields[[6]]$options

# Update form with subject, submit, and extract data frame(s).
form <- set_values(form, 'ctl00$MainContent$SubjectList' = subjects[1])
session <- submit_form(session, form, "ctl00$MainContent$Button1")

df_list <- html_table(session, T, T, T)

Две вещи, о которых нужно знать:

  1. df_list возвращает список фреймов данных, которые вам понадобятся объединить. Я рекомендую dplyr::bind_rows().
  2. Вам понадобятся два цикла: внешний l oop для семестров и внутренний l oop для предметов в каждом семестре.
...