【问题标题】:how to download a large binary file with RCurl *after* server authentication如何在服务器身份验证后使用 RCurl *下载大型二进制文件
【发布时间】:2013-06-24 03:16:17
【问题描述】:

我最初询问this question 关于使用httr 包执行此任务,但我认为使用httr 是不可能的。所以我重写了我的代码以使用 RCurl 代替 - 但我仍然在可能与 writefunction 相关的东西上绊倒......但我真的不明白为什么。

您应该能够使用 32 位版本的 R 来重现我的工作,因此如果您将任何内容读入 RAM,就会达到内存限制。我需要一个直接下载到硬盘的解决方案。

首先,此代码工作 -- 压缩文件被适当地保存到磁盘。

library(RCurl)
filename <- tempfile()
f <- CFILE(filename, "wb")
url <- "http://www2.census.gov/acs2011_5yr/pums/csv_pus.zip"
curlPerform(url = url, writedata = f@ref)
close(f)
# 2.1 GB file successfully written to disk

现在这里有一些无效的RCurl 代码。正如the previous question 中所述,要准确复制它需要在ipums 上创建一个提取。

your.email <- "email@address.com"
your.password <- "password"
extract.path <- "https://usa.ipums.org/usa-action/downloads/extract_files/some_file.csv.gz"

library(RCurl)

values <- 
    list(
        "login[email]" = your.email , 
        "login[password]" = your.password , 
        "login[is_for_login]" = 1
    )

curl = getCurlHandle()

curlSetOpt(
    cookiejar = 'cookies.txt', 
    followlocation = TRUE, 
    autoreferer = TRUE, 
    ssl.verifypeer = FALSE,
    curl = curl
)

params <- 
    list(
        "login[email]" = your.email , 
        "login[password]" = your.password , 
        "login[is_for_login]" = 1
    )

html <- postForm("https://usa.ipums.org/usa-action/users/validate_login", .params = params, curl = curl)
dl <- getURL( "https://usa.ipums.org/usa-action/extract_requests/download" , curl = curl)

现在我已登录,尝试与上述相同的命令,但使用 curl 对象来保留 cookie。

filename <- tempfile()
f <- CFILE(filename, mode = "wb")

这行换行--

curlPerform(url = extract.path, writedata = f@ref, curl = curl)
close(f)

# the error is:
Error in curlPerform(url = extract.path, writedata = f@ref, curl = curl) : 
  embedded nul in string: [[binary jibberish here]]

我上一篇文章的答案将我推荐给this c-level writefunction 答案,但我不知道如何重新创建 curl_writer C 程序(在 Windows 上?)..

dyn.load("curl_writer.so")
writer <- getNativeSymbolInfo("writer", PACKAGE="curl_writer")$address
curlPerform(URL=url, writefunction=writer)

..或者为什么它甚至是必要的,因为这个问题顶部的五行代码没有像getNativeSymbolInfo 这样疯狂的工作。我只是不明白为什么传入那个额外的 curl 对象来存储身份验证/cookie 并告诉它不要验证 SSL 会导致原本可以工作的代码..中断?

【问题讨论】:

  • 如果您编辑添加curl = getCurlHandle()curlPerform(url = url, writedata = f@ref, curl = curl) 的代码会发生什么?并且,一旦会话开始,您是否能够下载其他内容?例如使用curlPerformwritedata保存https://usa.ipums.org/usa-action/extract_requests/download
  • 关于C代码,需要先编译成DLL,然后dyn.load("curl_writer.dll")
  • 1) 我不明白您的编辑 getCurlHandle() 与我的代码有何不同? 2) 是的,我可以在会话开始后下载其他内容。 z &lt;- getBinaryURL( extract.path , curl = curl ) 有效,但它会将所有内容读入 RAM,因此无法解决我的问题。 3) 是否可以在 Windows 上的 R 中执行此操作?谢谢!! :)
  • 使用 Visual C++ 或 cigwin 编译代码,或查看此页面:stat.ethz.ch/R-manual/R-devel/library/utils/html/SHLIB.html
  • @AstDerek 我有没有机会说服你提供一个从头到尾的工作示例? :) 我无法理解这种非 R 的东西..

标签: r web-scraping rcurl httr


【解决方案1】:

现在可以使用httr 包来实现。谢谢哈德利!

https://github.com/hadley/httr/issues/44

【讨论】:

    【解决方案2】:
    1. this link创建一个名为curl_writer.c的文件并将其保存到C:\&lt;folder where you save your R files&gt;

      #include <stdio.h>
      
      /**
       * Original code just sent some message to stderr
       */
      size_t writer(void *buffer, size_t size, size_t nmemb, void *stream) {
          fwrite(buffer,size,nmemb,(FILE *)stream);
          return size * nmemb;
      }
      
    2. 打开命令窗口,进入保存curl_writer.c的文件夹并运行R编译器

      c:> cd "C:\<folder where you save your R files>"
      c:> R CMD SHLIB -o curl_writer.dll curl_writer.c
      
    3. 打开 R 并运行您的脚本

      C:> R
      
      your.email <- "email@address.com"
      your.password <- "password"
      extract.path <- "https://usa.ipums.org/usa-action/downloads/extract_files/some_file.csv.gz"
      
      library(RCurl)
      
      values <- 
          list(
              "login[email]" = your.email , 
              "login[password]" = your.password , 
              "login[is_for_login]" = 1
          )
      
      curl = getCurlHandle()
      
      curlSetOpt(
          cookiejar = 'cookies.txt', 
          followlocation = TRUE, 
          autoreferer = TRUE, 
          ssl.verifypeer = FALSE,
          curl = curl
      )
      
      params <- 
          list(
              "login[email]" = your.email , 
              "login[password]" = your.password , 
              "login[is_for_login]" = 1
          )
      
      html <- postForm("https://usa.ipums.org/usa-action/users/validate_login", .params = params, curl = curl)
      dl <- getURL( "https://usa.ipums.org/usa-action/extract_requests/download" , curl = curl)
      
      # Load the DLL you created
      # "writer" is the name of the function
      # "curl_writer" is the name of the dll
      dyn.load("curl_writer.dll")
      writer <- getNativeSymbolInfo("writer", PACKAGE="curl_writer")$address
      
      # Note that "URL" parameter is upper case, in your code it is lowercase
      # I'm not sure if that has something to do
      # "writer" is the symbol defined above
      f <- CFILE(filename <- tempfile(), "wb")
      curlPerform(URL=url, writedata=f@ref, writefunction=writer, curl=curl)
      close(f)
      

    【讨论】:

    • 谢谢!! ..但是当我在 Windows 中运行它时 - setwd( "C:/My Directory" ) ; cwr &lt;- "#include &lt;stdio.h&gt;\n\nsize_t writer(void *buffer, size_t size, size_t nmemb, void *stream) {\nfwrite(buffer,size,nmemb,(FILE *)stream);\nreturn size * nmemb;\n}" ; writeLines( cwr , "curl_writer.c" ) ; shell( "'C:\\Program Files\\R\\R-3.0.0\\bin\\x64\\Rcmd.exe' SHLIB -o 'C:\\My Directory\\curl_writer.dll' 'C:\\My Directory\\curl_writer.c'" ) - 我得到 The filename, directory name, or volume label syntax is incorrect.[[snip]]execution failed with error code 1 知道有什么问题吗?我想把它保存在 R 中 :)
    • system2(command="R",args="CMD SHLIB -o curl_writer.dll curl_writer.c") 而不是 shell(...)
    • 再次谢谢你,如果我在这里遗漏了一些明显的东西,我很抱歉。R 不在我的路径中,所以我使用了system2( command = "C:\\Program Files\\R\\R-3.0.0\\bin\\x64\\R.exe" , args = "CMD SHLIB -o curl_writer.dll curl_writer.c" ),但这给出了警告running command '"C:\Program Files\R\R-3.0.0\bin\x64\R.exe" CMD SHLIB -o curl_writer.dll curl_writer.c' had status 1 并没有't 创建 .dll 文件.. :/
    • 老实说,我不确定,我使用的是 Mac,它在这里没有问题。也许您需要安装编译器或其他东西?您可以请其他人为您编译 DLL 吗?
    • 此解决方案需要安装编译器。在 linux 和 mac 上通常是这种情况,但在 windows 上则不然。因此,您可能需要手动安装 C 编译器(并可能告诉 R 在哪里找到它)。
    猜你喜欢
    • 2014-11-30
    • 2019-02-16
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    相关资源
    最近更新 更多