Ответ 1
Это был хороший вызов!
Проблема не связана с языком R. Мы будем иметь тот же результат на любом языке, если просто попробуем опубликовать некоторые данные для загрузки script. Здесь мы имеем дело с каким-то "шаблоном" безопасности. Сайт запрещает пользователям извлекать URL-адреса файлов, и он просит их заполнить формы данными для предоставления этих ссылок. Если браузер может получить эти ссылки, мы также можем написать соответствующие HTTP-вызовы. Дело в том, что нам нужно точно знать, какие вызовы мы должны сделать. Чтобы найти это, нам нужно увидеть индивидуальные вызовы, которые делает сайт, когда кто-то нажимает на скачивание. Вот что я нашел несколько звонков перед успешным вызовом 302 AJDownload.jsp
POST
:
Мы можем видеть это ясно, если мы посмотрим на источник AJDocumentation.jsp
, он делает эти вызовы с помощью 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");
Затем, несколько вызовов ниже, мы можем увидеть успешный POST /AJDownload.jsp
со статусом 302 Moved Temporarily
и с желаемым Location
в его заголовках ответов:
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
Итак, это механизм безопасности этого сайта. Он использует ipinfo.io для хранения информации о посетителях об их IP-адресе, местоположении и даже организации ISP непосредственно перед тем, как пользователь начнет загрузку нажав на ссылку. script, который принимает эти данные, является /jdsStatJD.jsp
. Я havent использовал ipinfo.io, а также их ключ API для этой службы (они были скрыты на моих снимках экрана), и вместо этого я создал фиктивную действительную последовательность данных, просто чтобы проверить запрос. Данные формы сообщения для "защищенных" файлов вообще не требуются. Можно загружать файлы, не публикуя эти данные.
Кроме того, библиотека curlconverter
не требуется. Все, что нам нужно сделать, это простые запросы GET
и POST
с использованием библиотеки httr
. Одна из важных моментов, которые я хочу отметить, заключается в том, что для предотвращения использования функции httr
POST
после заголовка Location
, полученного с состоянием 302
при нашем последнем вызове, нам нужно использовать настройку конфигурации config(followlocation = FALSE)
что, конечно, не позволит ему следовать за Location
и выберем Location
из заголовков.
OUTPUT
My R script может быть запущен из командной строки и может принимать DOID
числовые значения параметров для получения необходимого файла. Например, если мы хотим получить ссылку на файл WVS_Longitudinal_1981-2014_stata_dta_v_2015_04_18
, тогда мы должны добавить его DOID
(который равен 3724) в конец нашего script при вызове с помощью команды Rscript
:
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"
Я создал функцию R, чтобы получить каждое местоположение файла, которое вы хотите, просто передав DOID
:
getFileById <- function(fileId)
Вы можете удалить синтаксический анализ аргумента командной строки и использовать функцию, передав DOID
напрямую:
#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)
Финальная работа R script
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)