Đâ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.jsp
POST
gọi:
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/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 GET
và POST
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 httr
POST
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)
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. –
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
Bỏ phiếu không rõ ràng theo http://stackoverflow.com/questions/40498277/programmatically-scraping-a-response-header-within-r#comment68826373_40786535 –