2016-11-08 20 views
10

Tôi đang cố truy cập vào tiêu đề phản hồi được đánh dấu: văn bản vị trí trong ảnh chụp màn hình bên dưới chỉ sử dụng thư viện webscraping dựa trên curl. người ta có thể dễ dàng đến điểm này trong bất kỳ trình duyệt web nào bằng cách truy cập http://www.worldvaluessurvey.org/WVSDocumentationWVL.jsp, nhấp vào tải xuống cho bất kỳ tệp dữ liệu nào và điền vào biểu mẫu thỏa thuận. Quá trình tải xuống sẽ tự động bắt đầu trong trình duyệt web.Lập trình cào tiêu đề phản hồi trong R

enter image description here

Tôi tin rằng cách duy nhất để có được một cookie hợp lệ là với library(curlconverter) (xem How to download a file behind a semi-broken javascript asp function with R) nhưng câu trả lời mà không xuất hiện để có đủ để lập trình xác định url http của tập tin, chỉ để tải xuống tệp nén sau khi nó đã được biết.

Tôi đã dán một số mã bên dưới với mã bảo vệ và mã curlconverter khác nhau mà tôi đã chơi cùng, nhưng tôi thiếu một số thứ ở đây. Một lần nữa, mục tiêu duy nhất là lập trình xác định toàn bộ văn bản được đánh dấu hoàn toàn trong R (nền tảng chéo).

library(curlconverter) 
library(httr) 

browserPOST <- 
    "curl 'http://www.worldvaluessurvey.org/AJDownload.jsp' 
    -H 'Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' 
    -H 'Accept-Encoding:gzip, deflate' 
    -H 'Accept-Language:en-US,en;q=0.8' 
    -H 'Cache-Control:max-age=0' 
    --compressed -H 'Connection:keep-alive' 
    -H 'Content-Length:188' 
    -H 'Content-Type:application/x-www-form-urlencoded' 
    -H 'Cookie:ASPSESSIONIDCASQAACD=IBLGBFOAEHFILMMJJCFEOEMI; JSESSIONID=50DABDEDD0B2FC370C415B4BD1855260; __atuvc=13%7C45; __atuvs=58224f37d312c42400c' 
    -H 'Host:www.worldvaluessurvey.org' 
    -H 'Origin:http://www.worldvaluessurvey.org' 
    -H 'Referer:http://www.worldvaluessurvey.org/AJDownloadLicense.jsp' 
    -H 'Upgrade-Insecure-Requests:1' 
    -H 'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36'" 

form_data <- 
    list( 
     ulthost = "WVS" , 
     CMSID = "" , 
     LITITLE = "" , 
     LINOMBRE = "fas" , 
     LIEMPRESA = "asf" , 
     LIEMAIL = "asdf" , 
     LIPROJECT = "asfd" , 
     LIUSE = "1" , 
     LIPURPOSE = "asdf" , 
     LIAGREE = "1" , 
     DOID = "3996" , 
     CndWAVE = "-1" , 
     SAID = "-1" , 
     AJArchive = "WVS Data Archive" , 
     EdFunction = "" , 
     DOP = "" 
    ) 



getDATA <- (straighten(browserPOST) %>% make_req)[[1]]() 

a <- VERB(verb = "POST", url = "http://www.worldvaluessurvey.org/AJDownload.jsp", 
    httr::add_headers(Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 
     `Accept-Encoding` = "gzip, deflate", `Accept-Language` = "en-US,en;q=0.8", 
     `Cache-Control` = "max-age=0", Connection = "keep-alive", 
     `Content-Length` = "188", Host = "www.worldvaluessurvey.org", 
     Origin = "http://www.worldvaluessurvey.org", Referer = "http://www.worldvaluessurvey.org/AJDownloadLicense.jsp", 
     `Upgrade-Insecure-Requests` = "1", `User-Agent` = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36"), 
    httr::set_cookies(`Cookie:ASPSESSIONIDCASQAACD` = "IBLGBFOAEHFILMMJJCFEOEMI", 
     JSESSIONID = "50DABDEDD0B2FC370C415B4BD1855260", `__atuvc` = "13%7C45", 
     `__atuvs` = "58224f37d312c42400c"), encode = "form",body=form_data) 
+2

Tôi đã thêm dấu chấm câu và câu hỏi của bạn. Vui lòng xem xét tự làm điều này trong tương lai vì chúng tôi cố gắng duy trì các tiêu chuẩn chất lượng tốt cho hàng chục nghìn người có thể đọc sách này theo thời gian. –

+0

Một vấn đề ở đây là các liên kết được nhúng trong khung nội tuyến được nhúng trong iframe khác. Cạo những thứ không dễ dàng, để nhẹ nhàng. – yeedle

+0

Bỏ phiếu không rõ ràng theo http://stackoverflow.com/questions/40498277/programmatically-scraping-a-response-header-within-r#comment68826373_40786535 –

Trả lời

5

Đây là một thử thách tuyệt vời!

Sự cố không liên quan đến ngôn ngữ R. Chúng tôi sẽ có kết quả tương tự trong bất kỳ ngôn ngữ nào nếu chúng tôi chỉ cố đăng một số dữ liệu lên tập lệnh tải xuống. Chúng ta phải đối phó với một số loại “mô hình” an ninh ở đây. Trang web hạn chế người dùng truy xuất url của tệp và yêu cầu họ điền biểu mẫu với dữ liệu để cung cấp các liên kết đó. Nếu trình duyệt có thể truy xuất các liên kết này, thì chúng tôi cũng có thể bằng cách viết các cuộc gọi HTTP thích hợp. Thing là, chúng ta cần phải biết chính xác những cuộc gọi mà chúng ta phải thực hiện. Để tìm thấy điều đó, chúng tôi cần phải xem từng cuộc gọi mà trang web thực hiện bất cứ khi nào có ai đó nhấp để tải xuống. Đây là những gì tôi tìm thấy một vài cuộc gọi trước khi một thành công 302 AJDownload.jspPOST gọi:

Http requests

Chúng ta có thể nhìn thấy nó rõ ràng, nếu chúng ta nhìn vào các nguồn AJDocumentation.jsp, nó làm cho các cuộc gọi bằng cách sử dụng jQuery $.get:

$.get("http://ipinfo.io?token=xxxxxxxxxxxxxx", function (response) { 
    var geodatos=encodeURIComponent(response.ip+"\t"+response.country+"\t"+response.postal+"\t"+ 
    response.loc+"\t"+response.region+"\t"+response.city+"\t"+ 
    response.org); 

    $.get("jdsStatJD.jsp?ID="+geodatos+ 
     "&url=http%3A%2F%2Fwww.worldvaluessurvey.org%2FAJDocumentation.jsp&referer=null&cms=Documentation", 
     function (resp2) { 
    }); 
}, "jsonp"); 

sau đó, một vài cuộc gọi dưới đây, chúng ta có thể thấy thành công POST /AJDownload.jsp với tình trạng 302 Moved Temporarily và với sự muốn Location trong tiêu đề phản ứng của nó:

Http requests

HTTP/1.1 302 Moved Temporarily 
Content-Length: 0 
Content-Type: text/html 
Location: http://www.worldvaluessurvey.org/wvsdc/CO00001/F00003724-WVS_Longitudinal_1981-2014_stata_dta_v_2015_04_18.zip 
Server: Microsoft-IIS/7.5 
X-Powered-By: ASP.NET 
Date: Thu, 01 Dec 2016 16:24:37 GMT 

Vì vậy, đây là cơ chế bảo mật của trang web này. Nó sử dụng ipinfo.io để lưu trữ thông tin khách truy cập về IP, Vị trí của họ và ngay cả tổ chức ISP, ngay trước khi người dùng sắp bắt đầu tải xuống bằng cách nhấp vào liên kết. Tập lệnh nhận dữ liệu này là /jdsStatJD.jsp. Tôi đã không sử dụng ipinfo.io, cũng không phải khóa API của họ cho dịch vụ này (có ẩn trên ảnh chụp màn hình của tôi) và thay vào đó tôi đã tạo một chuỗi dữ liệu hợp lệ giả, chỉ để xác thực yêu cầu. Dữ liệu biểu mẫu bài đăng cho các tệp "được bảo vệ" không yêu cầu gì cả. Có thể tải xuống các tệp mà không đăng những dữ liệu này.

Ngoài ra, thư viện curlconverter không bắt buộc. Tất cả những gì chúng tôi phải làm là đơn giản GETPOST yêu cầu bằng cách sử dụng thư viện httr. Một phần quan trọng tôi muốn chỉ ra, đó là để ngăn chặn chức năng httrPOST tuân theo tiêu đề Location được nhận với trạng thái 302 tại cuộc gọi cuối cùng của chúng tôi, chúng tôi cần sử dụng cài đặt cấu hình config(followlocation = FALSE), tất nhiên sẽ ngăn không cho nó theo sau Location và để chúng tôi tìm nạp Location từ các tiêu đề.

OUTPUT

kịch bản R của tôi có thể được chạy từ dòng lệnh và nó có thể chấp nhận DOID giá trị số cho các thông số để có được các tập tin cần thiết. Ví dụ, nếu chúng ta muốn có được sự liên kết cho file WVS_Longitudinal_1981-2014_stata_dta_v_2015_04_18, thì chúng ta phải thêm nó DOID (đó là 3724) đến hết kịch bản của chúng tôi khi gọi nó bằng cách sử dụng Rscript lệnh:

Rscript wvs_fetch_downloads.r 3724 
[1] "http://www.worldvaluessurvey.org/wvsdc/CO00001/F00003724-WVS_Longitudinal_1981-2014_stata_dta_v_2015_04_18.zip" 

tôi đã tạo ra một chức năng R để nhận được mỗi vị trí tập tin bạn muốn bằng cách chỉ đi qua các DOID:

getFileById <- function(fileId) 

bạn có thể loại bỏ các đối số dòng lệnh phân tích và sử dụng các chức năng bằng cách truyền DOID trực tiếp:

#args <- commandArgs(TRUE) 
#if(length(args) == 0) { 
# print("No file id specified. Use './script.r ####'.") 
# quit("no") 
#} 

#fileId <- args[1] 
fileId <- "3724" 

# DOID=3843 : WVS_EVS_Integrated_Dictionary_Codebook v_2014_09_22 (Excel) 
# DOID=3844 : WVS_Values Surveys Integrated Dictionary_TimeSeries_v_2014-04-25 (Excel) 
# DOID=3725 : WVS_Longitudinal_1981-2014_rdata_v_2015_04_18 
# DOID=3996 : WVS_Longitudinal_1981-2014_sas_v_2015_04_18 
# DOID=3723 : WVS_Longitudinal_1981-2014_spss_v_2015_04_18 
# DOID=3724 : WVS_Longitudinal_1981-2014_stata_dta_v_2015_04_18 

getFileById(fileId) 

cuối cùng R làm việc kịch bản

library(httr) 

getFileById <- function(fileId) { 
    response <- GET(
     url = "http://www.worldvaluessurvey.org/AJDocumentation.jsp?CndWAVE=-1", 
     add_headers(
      `Accept` = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 
      `Accept-Encoding` = "gzip, deflate", 
      `Accept-Language` = "en-US,en;q=0.8", 
      `Cache-Control` = "max-age=0", 
      `Connection` = "keep-alive", 
      `Host` = "www.worldvaluessurvey.org", 
      `User-Agent` = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0", 
      `Content-type` = "application/x-www-form-urlencoded", 
      `Referer` = "http://www.worldvaluessurvey.org/AJDownloadLicense.jsp", 
      `Upgrade-Insecure-Requests` = "1")) 

    set_cookie <- headers(response)$`set-cookie` 
    cookies <- strsplit(set_cookie, ';') 
    cookie <- cookies[[1]][1] 

    response <- GET(
     url = "http://www.worldvaluessurvey.org/jdsStatJD.jsp?ID=2.72.48.149%09IT%09undefined%0941.8902%2C12.4923%09Lazio%09Roma%09Orange%20SA%20Telecommunications%20Corporation&url=http%3A%2F%2Fwww.worldvaluessurvey.org%2FAJDocumentation.jsp&referer=null&cms=Documentation", 
     add_headers(
      `Accept` = "*/*", 
      `Accept-Encoding` = "gzip, deflate", 
      `Accept-Language` = "en-US,en;q=0.8", 
      `Cache-Control` = "max-age=0", 
      `Connection` = "keep-alive", 
      `X-Requested-With` = "XMLHttpRequest", 
      `Host` = "www.worldvaluessurvey.org", 
      `User-Agent` = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0", 
      `Content-type` = "application/x-www-form-urlencoded", 
      `Referer` = "http://www.worldvaluessurvey.org/AJDocumentation.jsp?CndWAVE=-1", 
      `Cookie` = cookie)) 

    post_data <- list( 
     ulthost = "WVS", 
     CMSID = "", 
     CndWAVE = "-1", 
     SAID = "-1", 
     DOID = fileId, 
     AJArchive = "WVS Data Archive", 
     EdFunction = "", 
     DOP = "", 
     PUB = "") 

    response <- POST(
     url = "http://www.worldvaluessurvey.org/AJDownload.jsp", 
     config(followlocation = FALSE), 
     add_headers(
      `Accept` = "*/*", 
      `Accept-Encoding` = "gzip, deflate", 
      `Accept-Language` = "en-US,en;q=0.8", 
      `Cache-Control` = "max-age=0", 
      `Connection` = "keep-alive", 
      `Host` = "www.worldvaluessurvey.org", 
      `User-Agent` = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0", 
      `Content-type` = "application/x-www-form-urlencoded", 
      `Referer` = "http://www.worldvaluessurvey.org/AJDocumentation.jsp?CndWAVE=-1", 
      `Cookie` = cookie), 
     body = post_data, 
     encode = "form") 

    location <- headers(response)$location 
    location 
} 

args <- commandArgs(TRUE) 
if(length(args) == 0) { 
    print("No file id specified. Use './script.r ####'.") 
    quit("no") 
} 

fileId <- args[1] 

# DOID=3843 : WVS_EVS_Integrated_Dictionary_Codebook v_2014_09_22 (Excel) 
# DOID=3844 : WVS_Values Surveys Integrated Dictionary_TimeSeries_v_2014-04-25 (Excel) 
# DOID=3725 : WVS_Longitudinal_1981-2014_rdata_v_2015_04_18 
# DOID=3996 : WVS_Longitudinal_1981-2014_sas_v_2015_04_18 
# DOID=3723 : WVS_Longitudinal_1981-2014_spss_v_2015_04_18 
# DOID=3724 : WVS_Longitudinal_1981-2014_stata_dta_v_2015_04_18 

getFileById(fileId) 
+0

Vâng, bạn đã làm điều đó - lần này. Đối với bất kỳ trường hợp nào khác - và mọi lúc mọi thứ thay đổi tại trang web - điều này sẽ cần phải thực hiện lại tất cả, và nó sẽ là cùng một loại thử thách - quay lại bản vẽ mỗi lần. Điều này thực sự là một nhiệm vụ cho một trình duyệt không đầu. P.S. Tôi bây giờ trớ trêu thay thấy điều này trong bảng điều khiển bên: http://security.stackexchange.com/questions/144155/giving-malicious-crawlers-and-scripts-a-hard-time –

+0

@ivan_pozdeev Bạn đang mở một chủ đề lớn về bảo mật đây. Câu hỏi OPs là về một ứng dụng web cụ thể và đối với một số tệp cụ thể. Tất nhiên, khi ứng dụng được nâng cấp với mẫu bảo mật mạnh nhất, mã tìm nạp này sẽ bị hỏng. Các nhà phát triển có thể đã sử dụng ngay cả một dịch vụ captcha để bảo vệ các hình thức của họ từ các chương trình nạo như thế này ở đây. Tôi vừa thực hiện việc đảo ngược các yêu cầu HTTP để tìm ra những gì nó đã được gửi đến máy chủ để trả lại kết quả mong muốn, đó là phản hồi '302' với tệp mà nó yêu cầu. Đây là những gì OP đang tìm kiếm. –

+0

@ivan_pozdeev Tôi tự hỏi làm thế nào một trình duyệt * không đầu * thành công có thể tiếp tục tìm nạp một yêu cầu như vậy nếu nó thay đổi mẫu của nó và thậm chí nếu các nhà phát triển thêm sự bảo vệ như captcha. Tôi không nghĩ điều đó là có thể, nhưng bạn có thể vui lòng cung cấp một số tài nguyên với các ví dụ như vậy không và cách trình duyệt * không đầu có thể tiếp tục và trả lại kết quả mong muốn sau khi phương thức bảo mật đã thay đổi hoàn toàn hoặc một phần? Tôi không biết nhiều về trình duyệt * không đầu * và tôi muốn tìm hiểu thêm về chủ đề này. –

0

Theo the source of the underlying httr::request_perform, đối tượng bạn nhận được từ VERB() trông như thế này:

res <- response(
    url = resp$url, 
    status_code = resp$status_code, 
    headers = headers, 
    all_headers = all_headers, 
    cookies = curl::handle_cookies(handle), 
    content = resp$content, 
    date = date, 
    times = resp$times, 
    request = req, 
    handle = handle 
) 

Vì vậy, bạn quan tâm đến nó headers hoặc all_headers (response is but a structure). Nếu một chuyển hướng có liên quan, all_headers sẽ có nhiều bộ tiêu đề được trả về bởi curl::parse_headers(), headers luôn là tập hợp cuối cùng.

+0

hi, xin lỗi, tôi đang downvoting vì các đối tượng 'a $ headers' và' a $ all_headers' từ ví dụ của tôi trong câu hỏi không giải quyết được vấn đề đã nêu –

+1

@AnthonyDamico vấn đề đã nêu là "Lập trình xóa tiêu đề phản hồi trong R ", và nó làm điều đó. Nếu vấn đề thực sự là "cạo một trang cụ thể cho bạn" (tức là xác định tập hợp các yêu cầu nào cần thiết để lập trình đến tệp trên trang cụ thể đó), đó là một vấn đề hoàn toàn khác với vấn đề được nêu. –

+0

@AnthonyDamico, cá nhân tôi nghĩ rằng phiếu giảm giá đang được sử dụng nhẹ rất thường xuyên trong SO.Bạn đã đăng câu hỏi, một người đã nỗ lực giúp đỡ. Nếu bạn chỉ đơn giản giải thích trong một bình luận tại sao câu trả lời đó không giải quyết được vấn đề, phần lớn thời gian, bạn sẽ chỉ nhận được sự giúp đỡ nhiều hơn. Bạn thấy làm thế nào điều này có thể được thực hiện như là một thiếu tôn trọng cho những nỗ lực đã được đưa vào cố gắng để giúp đỡ. –

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