【问题标题】:Scraping web page that is only accesible after submitting aspx form抓取只有在提交 aspx 表单后才能访问的网页
【发布时间】:2020-03-31 19:22:31
【问题描述】:

我需要抓取一个只有在提交 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> '':

reprex package (v0.3.0) 于 2020 年 3 月 23 日创建

第一个列表项是标题搜索栏。第二个可能是表单,但如果是这样,它没有提交值。

我可以使用一些帮助来确定如何模拟该表单提交以便我可以获取文件表,或者确定是否有一个 URL 可以访问相同的结果页面。

【问题讨论】:

    标签: r rvest


    【解决方案1】:

    这很棘手,但可能。

    您遇到的第一个困难是,当您向 URL“https://nces.ed.gov/ipeds/datacenter/DataFiles.aspx”发送 GET 请求(通过 html_session)时,您发送的请求没有任何会话 cookie。这会使服务器将您重定向到另一个页面“https://nces.ed.gov/ipeds/use-the-data”,而您在变量sesh 中看到的正是此页面。

    但是,由于 rvest(实际上是 rvest 下的 httr)重复使用会话句柄,因此您需要做的就是导航到登录页面,这允许 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")
    

    最后,我们需要手动添加一个通常通过 javascript 添加的 cookie:

    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
    

    reprex package (v0.3.0) 于 2020 年 3 月 31 日创建

    【讨论】:

    • 难以置信,这绝对超出了我的能力范围。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    相关资源
    最近更新 更多