2013-06-26 30 views
9

tôi đã hỏi this question về việc thực hiện tác vụ này với gói httr, nhưng tôi không nghĩ rằng nó có thể sử dụng httr. vì vậy tôi đã viết lại mã của mình để sử dụng RCurl thay thế - nhưng tôi vẫn đang vấp phải thứ gì đó có thể liên quan đến writefunction .. nhưng tôi thực sự không hiểu tại sao.cách tải xuống tệp nhị phân lớn với RCurl * sau khi xác thực * máy chủ

bạn sẽ có thể sao chép tác phẩm của mình bằng cách sử dụng phiên bản R bit 32 bit, do đó bạn sẽ đạt đến giới hạn bộ nhớ nếu bạn đọc bất kỳ thứ gì vào RAM. tôi cần một giải pháp tải trực tiếp vào đĩa cứng.

để bắt đầu, mã này để hoạt động - tệp được nén được lưu thích hợp vào đĩa.

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

bây giờ đây là một số mã RCurl không hoạt động. như đã nêu trong the previous question, sao chép chính xác điều này sẽ yêu cầu tạo một trích xuất trên ipums.

your.email <- "[email protected]" 
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) 

và bây giờ tôi đã đăng nhập, hãy thử các lệnh giống như trên, nhưng với đối tượng curl để giữ cookie.

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

dòng này breaks--

curlPerform(url = extract.path, writedata = [email protected], curl = curl) 
close(f) 

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

câu trả lời cho bài trước của tôi gọi tôi đến this c-level writefunction câu trả lời, nhưng tôi không biết gì về làm thế nào để tái tạo mà chương trình curl_writer C (trên cửa sổ?) ..

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

..or lý do tại sao nó thậm chí còn cần thiết, cho rằng năm dòng mã ở trên cùng của công việc câu hỏi này mà không cần bất cứ điều gì điên như getNativeSymbolInfo. tôi chỉ không hiểu tại sao đi qua trong đó thêm curl đối tượng lưu trữ xác thực/cookie và nói với nó không để xác minh SSL sẽ gây ra mã mà nếu không hoạt động .. để phá vỡ?

+0

gì xảy ra nếu bạn chỉnh sửa mã mà công trình thêm 'curl = getCurlHandle() 'và' curlPerform (url = url, writedata = f @ ref, curl = curl) '? và, bạn có thể tải xuống một số nội dung khác sau khi phiên đã bắt đầu không? ví dụ, sử dụng 'curlPerform' và' writedata' để lưu 'https: //usa.ipums.org/usa-action/extract_requests/download' –

+0

Về mã C, bạn cần biên dịch nó thành một DLL, và sau đó là 'dyn.load (" curl_writer.dll ")' –

+0

1) tôi không hiểu làm thế nào của bạn getCurlHandle chỉnh sửa() là bất kỳ khác nhau từ mã của tôi? 2) có, tôi có thể tải xuống nội dung khác sau khi phiên bắt đầu. 'z <- getBinaryURL (extract.path, curl = curl)' hoạt động, nhưng nó đọc mọi thứ thành RAM và do đó không giải quyết được vấn đề của tôi. 3) là nó có thể làm điều này trong R trên cửa sổ? cảm ơn!! :) –

Trả lời

2
  1. Từ this link tạo một file có tên curl_writer.c và lưu nó vào C:\<folder where you save your R files>

    #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. mở một cửa sổ lệnh, đi đến thư mục mà bạn đã lưu curl_writer.c và chạy trình biên dịch R

    c:> cd "C:\<folder where you save your R files>" 
    c:> R CMD SHLIB -o curl_writer.dll curl_writer.c 
    
  3. Mở R và chạy tập lệnh của bạn

    C:> R 
    
    your.email <- "[email protected]" 
    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, [email protected], writefunction=writer, curl=curl) 
    close(f) 
    
+0

cảm ơn !! .. nhưng khi tôi chạy nó trong các cửa sổ - 'setwd (" C:/My Directory "); cwr <- "#include \ n \ nsize_t writer (void * buffer, size_t size, size_t nmemb, void * stream) {\ nfwrite (bộ đệm, kích thước, nmemb, (FILE *) stream); \ nquay lại kích thước * nmemb; \ n} "; writeLines (cwr, "curl_writer.c"); shell ("'C: \\ Program Files \\ R \\ R-3.0.0 \\ bin \\ x64 \\ Rcmd.exe' SHLIB -o 'C: \\ Thư mục của tôi \\ curl_writer.dll' 'C : \\ Thư mục của tôi \\ curl_writer.c '")' - tôi nhận được 'Cú pháp tên tập tin, tên thư mục, hoặc nhãn khối lượng không chính xác. [[Snip]] thực hiện thất bại với mã lỗi 1' bất kỳ ý tưởng gì là sai? tôi muốn giữ nó trong R :) –

+0

'system2 (lệnh =" R ", args =" CMD SHLIB -o curl_writer.dll curl_writer.c ")' thay vì 'shell (...)' –

+0

cảm ơn bạn một lần nữa, và xin lỗi nếu tôi đang thiếu một cái gì đó hiển nhiên ở đây .. 'R' không có trong PATH của tôi, vì vậy tôi đã sử dụng' system2 (lệnh = "C: \\ Program Files \\ R \\ R-3.0.0 \\ bin \\ x64 \\ R.exe ", args =" CMD SHLIB -o curl_writer.dll curl_writer.c ")' nhưng đã đưa ra cảnh báo 'lệnh chạy' "C: \ Program Files \ R \ R-3.0.0 \ bin \ x64 \ R.exe "CMD SHLIB -o curl_writer.dll curl_writer.c 'có trạng thái 1' và không tạo tệp' .dll' ..:/ –

Các vấn đề liên quan