14

我正在尝试使用 R 自动下载此网页上可用的收入动态面板研究文件。单击这些文件中的任何一个都会将用户带到此登录/身份验证页面。身份验证后,您可以使用 Web 浏览器轻松下载文件。不幸的是,下面的代码似乎没有维护身份验证。我已经尝试在 Chrome 中检查 Login.aspx 页面(如此处所述),但即使我相信我传递了所有正确的值,它似乎也无法维持身份验证。我不在乎它是否完成了httrHeadershttrRCurl或其他东西,我只是喜欢在 R 中工作的东西,所以我不需要这个脚本的用户必须手动或使用一些完全独立的程序下载文件。我的尝试之一如下,但它不起作用。任何帮助,将不胜感激。谢谢!!:D

require(httr)

values <- 
    list( 
        "ctl00$ContentPlaceHolder3$Login1$UserName" = "you@email.com" , 
        "ctl00$ContentPlaceHolder3$Login1$Password" = "somepassword" ,
        "ctl00$ContentPlaceHolder3$Login1$LoginButton" = "Log In" ,
        "_LASTFOCUS" = "" ,
        "_EVENTTARGET" = "" ,
        "_EVENTARGUMENT" = "" 
    )

POST( "http://simba.isr.umich.edu/u/Login.aspx?redir=http%3a%2f%2fsimba.isr.umich.edu%2fZips%2fZipMain.aspx" , body = values )

resp <- GET( "http://simba.isr.umich.edu/Zips/GetFile.aspx" , query = list( file = "1053" ) )
4

1 回答 1

12

除了在身份验证后存储 cookie(请参阅我上面的评论),您的解决方案中还有另一个问题点:ASP.net 站点VIEWSTATE在 cookie 中设置了一个键值对,该键值对将在您的查询中保留 - 如果您检查,您可以在您的示例中甚至没有登录(POST命令的结果包含有关如何登录的信息,只需检查一下)。

可能解决方案的概述:

  1. 加载RCurl包:

    > library(RCurl)
    
  2. 设置一些方便的curl选项:

    > curl = getCurlHandle()
    > curlSetOpt(cookiejar = 'cookies.txt', followlocation = TRUE, autoreferer = TRUE, curl = curl)
    
  3. 首次加载页面以捕获VIEWSTATE

    > html <- getURL('http://simba.isr.umich.edu/u/Login.aspx', curl = curl)
    
  4. VIEWSTATE使用正则表达式或任何其他工具提取:

    > viewstate <- as.character(sub('.*id="__VIEWSTATE" value="([0-9a-zA-Z+/=]*).*', '\\1', html))
    
  5. 将参数设置为您的用户名、密码VIEWSTATE

    > params <- list(
        'ctl00$ContentPlaceHolder3$Login1$UserName'    = '<USERNAME>',
        'ctl00$ContentPlaceHolder3$Login1$Password'    = '<PASSWORD>',
        'ctl00$ContentPlaceHolder3$Login1$LoginButton' = 'Log In',
        '__VIEWSTATE'                                  = viewstate
        )
    
  6. 最后登录:

    > html = postForm('http://simba.isr.umich.edu/u/Login.aspx', .params = params, curl = curl)
    

    恭喜,现在您已登录并curl持有 cookie 来验证!

  7. 验证您是否已登录:

    > grepl('Logout', html)
    [1] TRUE
    
  8. 因此,您可以继续下载任何文件 - 只需确保传递curl = curl您的所有查询。

于 2013-04-09T09:14:31.277 回答