Очистка веб-страницы, которая становится доступной только после отправки формы aspx - PullRequest
2 голосов
/ 23 марта 2020

Мне нужно очистить таблицу, которую можно просмотреть только после отправки формы aspx: https://nces.ed.gov/ipeds/datacenter/DataFiles.aspx (с выбранными «Все годы» и «Все опросы»). Я пытался получить форму, используя rvest, но не похоже, что она захватывает ту, которая мне нужна:

require(rvest)
#> Loading required package: rvest
#> Loading required package: xml2

url <- "https://nces.ed.gov/ipeds/datacenter/DataFiles.aspx"

sesh <- html_session(url)

forms <- sesh %>% html_nodes("form") %>% html_form()

forms
#> [[1]]
#> <form> 'HeaderSearch' (GET /search/search_redirect.asp)
#>   <input text> 'Search': Search
#>   <input hidden> 'website': NCES
#>   <input submit> '': Go
#> 
#> [[2]]
#> <form> 'search-box' (GET http://nces.ed.gov/search)
#>   <input hidden> 'output': xml_no_dtd
#>   <input hidden> 'client': nces
#>   <input hidden> 'site': nces
#>   <input hidden> 'sitesearch': nces.ed.gov/ipeds
#>   <input text> 'q': Search IPEDS
#>   <input image> '':

Создано в 2020-03-23 ​​пакетом contex (v0.3.0)

Первым элементом списка является панель поиска заголовка. Второй может быть форма, но если это так, у него нет значения отправки.

Я мог бы использовать некоторую помощь, либо выяснить, как эмулировать отправку этой формы, чтобы я мог получить таблицу файлов, или, в качестве альтернативы, выяснить, есть ли URL, который попадает на ту же страницу результатов.

1 Ответ

3 голосов
/ 31 марта 2020

Это сложно, но возможно.

Первая сложность, с которой вы сталкиваетесь, заключается в том, что при отправке запроса GET (через html_session) на URL-адрес "https://nces.ed.gov/ipeds/datacenter/DataFiles.aspx", Вы отправляете его без сессионных куки. Это заставляет сервер перенаправить вас на другую страницу, "https://nces.ed.gov/ipeds/use-the-data", и именно эту страницу вы видите в своей переменной sesh.

Однако, поскольку rvest ( на самом деле httr под rvest) повторно использует дескрипторы сеансов, все, что вам нужно сделать, чтобы преодолеть эту проблему, это перейти на страницу входа в систему, которая позволяет httr выбрать cookie-файлы сеанса, которые необходимо просмотреть как анонимный пользователь.

Здесь мы также установим для нашего пользовательского агента значение firefox.

library(httr)
library(rvest)
library(tibble)

url1    <- "https://nces.ed.gov/ipeds/datacenter/login.aspx?gotoReportId=8"
url2    <- "https://nces.ed.gov/ipeds/datacenter/DataFiles.aspx"

UA      <- "Mozilla/5.0 (Windows NT 6.1; rv:75.0) Gecko/20100101 Firefox/75.0"

html <- GET(url1, user_agent(UA))
html <- GET(url2, user_agent(UA))
page <- html %>% read_html()

Теперь page содержит страницу с формой, которую вы хотите отправить. И вот тут мы подходим ко второй трудности. Самый простой способ отправить форму с помощью rvest::submit_form(), но, похоже, это не работает, потому что не все поля заполнены. Поэтому нам нужно построить форму вручную с помощью инструментов очистки rvest:

form <- list(`__VIEWSTATE` = page %>%
                html_node(xpath = "//input[@name='__VIEWSTATE']") %>%
                html_attr("value"),
             `__VIEWSTATEGENERATOR` = page %>%
                html_node(xpath = "//input[@name='__VIEWSTATEGENERATOR']") %>%
                html_attr("value"),
             `__EVENTVALIDATION` = page %>%
                html_node(xpath = "//input[@name='__EVENTVALIDATION']") %>%
                html_attr("value"),
             `ctl00$contentPlaceHolder$ddlYears` = "-1",
             `ddlSurveys` = "-1",
             `ctl00$contentPlaceHolder$ibtnContinue.x` = sample(50, 1),
             `ctl00$contentPlaceHolder$ibtnContinue.y` = sample(20, 1))

Теперь мы можем отправить эту форму, , но , прежде чем мы сделаем это, нам нужно добавить несколько заголовков, без которых сервер выдаст http 500:

Headers <- add_headers(`Accept-Encoding` = "gzip, deflate, br", 
                       `Accept-Language` = "en-GB,en;q=0.5", 
                       `Connection` = "keep-alive", 
                       `Host` = "nces.ed.gov", 
                       `Origin` = "https://nces.ed.gov", 
                       `Referer` = url2, 
                       `Upgrade-Insecure-Requests` = "1")

Наконец, есть повар ie, который обычно добавляется через javascript, который нам нужно будет добавить вручную:

Cookies <- set_cookies(setNames(c(cookies(html)$value, "true"),
                                c(cookies(html)$name, "fromIpeds")))

Теперь мы можем опубликовать нашу форму с правильной формой, заголовками и файлами cookie, чтобы получить нужную страницу:

Result  <- POST(url2, body = form, user_agent(UA), Headers, Cookies)

Теперь вы можете очистить эту страницу так, как вам нравится. В качестве примера я покажу, что текст таблицы результатов можно довольно легко вырезать:

Result %>% 
 read_html() %>% 
 html_node("#contentPlaceHolder_tblResult") %>% 
 html_table() %>%
 as_tibble()
#> # A tibble: 1,090 x 7
#>     Year Survey    Title        `Data File` `Stata Data Fil~ Programs Dictionary
#>    <int> <chr>     <chr>        <chr>       <chr>            <chr>    <chr>     
#>  1  2018 Institut~ Directory i~ HD2018      HD2018_STATA     SPSS, S~ Dictionary
#>  2  2018 Institut~ Educational~ IC2018      IC2018_STATA     SPSS, S~ Dictionary
#>  3  2018 Institut~ Student cha~ IC2018_AY   IC2018_AY_STATA  SPSS, S~ Dictionary
#>  4  2018 Institut~ Student cha~ IC2018_PY   IC2018_PY_STATA  SPSS, S~ Dictionary
#>  5  2018 Institut~ Response st~ FLAGS2018   FLAGS2018_STATA  SPSS, S~ Dictionary
#>  6  2018 12-Month~ 12-month un~ EFFY2018    EFFY2018_STATA   SPSS, S~ Dictionary
#>  7  2018 12-Month~ 12-month in~ EFIA2018    EFIA2018_STATA   SPSS, S~ Dictionary
#>  8  2018 12-Month~ Response st~ FLAGS2018   FLAGS2018_STATA  SPSS, S~ Dictionary
#>  9  2018 Admissio~ Admission c~ ADM2018     ADM2018_STATA    SPSS, S~ Dictionary
#> 10  2018 Admissio~ Response st~ FLAGS2018   FLAGS2018_STATA  SPSS, S~ Dictionary
#> # ... with 1,080 more rows

Создан в 2020-03-31 пакетом Представить ( v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...