2016-01-06 32 views
8

Utknąłem na ciasteczkach podczas próby pobrania pliku PDF.Używanie R do akceptowania plików cookie w celu pobrania pliku PDF

Na przykład, jeśli mam DOI dla dokumentu PDF na Archeologii Data Service, to rozwiąże się this landing page z embedded link in it to this pdf ale które naprawdę przekierowuje do this inny link.

zajmie się rozwiązaniem problemu z DOI, a my wyodrębnimy URL ze strony docelowej za pomocą library(XML), ale utknąłem na samym pliku PDF.

Gdybym to zrobić:

download.file("http://archaeologydataservice.ac.uk/archiveDS/archiveDownload?t=arch-1352-1/dissemination/pdf/Dyfed/GL44004.pdf", destfile = "tmp.pdf") 

potem odebrać plik HTML, który jest taki sam jak http://archaeologydataservice.ac.uk/myads/

próbując odpowiedzieć na How to use R to download a zipped file from a SSL page that requires cookies prowadzi mnie do tego:

library(httr) 

terms <- "http://archaeologydataservice.ac.uk/myads/copyrights" 
download <- "http://archaeologydataservice.ac.uk/archiveDS/archiveDownload" 
values <- list(agree = "yes", t = "arch-1352-1/dissemination/pdf/Dyfed/GL44004.pdf") 

# Accept the terms on the form, 
# generating the appropriate cookies 

POST(terms, body = values) 
GET(download, query = values) 

# Actually download the file (this will take a while) 

resp <- GET(download, query = values) 

# write the content of the download to a binary file 

writeBin(content(resp, "raw"), "c:/temp/thefile.zip") 

Ale po funkcjach POST i GET po prostu otrzymuję kod HTML tej samej strony z ciasteczkami, którą otrzymałem z download.file:

> GET(download, query = values) 
Response [http://archaeologydataservice.ac.uk/myads/copyrights?from=2f6172636869766544532f61726368697665446f776e6c6f61643f61677265653d79657326743d617263682d313335322d3125324664697373656d696e6174696f6e2532467064662532464479666564253246474c34343030342e706466] 
    Date: 2016-01-06 00:35 
    Status: 200 
    Content-Type: text/html;charset=UTF-8 
    Size: 21 kB 
<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h... 
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> 
     <head> 
      <meta http-equiv="Content-Type" content="text/html; c... 


      <title>Archaeology Data Service: myADS</title> 

      <link href="http://archaeologydataservice.ac.uk/css/u... 
... 

Patrząc na http://archaeologydataservice.ac.uk/about/Cookies wydaje się, że sytuacja cookies na tej stronie jest skomplikowana. Wydaje się, że ten rodzaj złożoności plików cookie nie jest niczym niezwykłym dla dostawców danych w Wielkiej Brytanii: automating the login to the uk data service website in R with RCurl or httr

Jak mogę użyć R, aby ominąć ciasteczka na tej stronie?

Odpowiedz

6

Twoja prośba o numer rOpenSci została wysłuchana!

Istnieje wiele javascript między tymi stronami, co sprawia, że ​​jest nieco denerwujące, aby spróbować rozszyfrować poprzez httr + rvest. Wypróbuj RSelenium. To działało na załadowanym Firefoksie OS X 10.11.2, R 3.2.3 &.

library(RSelenium) 

# check if a sever is present, if not, get a server 
checkForServer() 

# get the server going 
startServer() 

dir.create("~/justcreateddir") 
setwd("~/justcreateddir") 

# we need PDFs to download instead of display in-browser 
prefs <- makeFirefoxProfile(list(
    `browser.download.folderList` = as.integer(2), 
    `browser.download.dir` = getwd(), 
    `pdfjs.disabled` = TRUE, 
    `plugin.scan.plid.all` = FALSE, 
    `plugin.scan.Acrobat` = "99.0", 
    `browser.helperApps.neverAsk.saveToDisk` = 'application/pdf' 
)) 
# get a browser going 
dr <- remoteDriver$new(extraCapabilities=prefs) 
dr$open() 

# go to the page with the PDF 
dr$navigate("http://archaeologydataservice.ac.uk/archives/view/greylit/details.cfm?id=17755") 

# find the PDF link and "hit ENTER" 
pdf_elem <- dr$findElement(using="css selector", "a.dlb3") 
pdf_elem$sendKeysToElement(list("\uE007")) 

# find the ACCEPT button and "hit ENTER" 
# that will save the PDF to the default downloads directory 
accept_elem <- dr$findElement(using="css selector", "a[id$='agreeButton']") 
accept_elem$sendKeysToElement(list("\uE007")) 

Teraz poczekaj na zakończenie pobierania. Konsola R nie będzie zajęta podczas pobierania, więc można łatwo zamknąć sesję, zanim pobieranie zostanie zakończone.

# close the session 
dr$close() 
+0

Dałem szansę na Ubuntu 14.04, R 3.2.3 i Firefox. 'dr $ open()' raporty '[1]" Łączenie ze zdalnym serwerem " Niezdefiniowany błąd w wywołaniu RCurl.Error w queryRD (paste0 (serverURL,"/session ")," POST ", qdata = toJSON (serverOpts)): ' –

+1

To zawsze była moja największa nić do wybrania z Selenium w ogóle (niekoniecznie R pkg). Uzyskanie spójności między Windows, OS X i * nix jest tak trudne.Mam nadzieję, że ludzie mogą do tego dodać (wszystkie moje systemy * nix są bardzo cienko skonfigurowanymi bezgłowymi serwerami i nie mam zamiaru próbować opanować dzisiejszego sterownika phantomjs :-) – hrbrmstr

+2

OK, znalazłem sposób, aby sprawić, żeby działał na moim komputer. Musiałem ręcznie uruchomić samodzielny serwer selenu za pomocą 'java -jar selenium-server-standalone-2.48.0.jar'. Wtedy mogę się połączyć. –

3

Ta odpowiedź pochodzi z John Harrison mailem, pisał tu na jego prośbę:

To pozwoli Ci pobrać PDF:

appURL <- "http://archaeologydataservice.ac.uk/archiveDS/archiveDownload?t=arch-1352-1/dissemination/pdf/Dyfed/GL44004.pdf" 
library(RCurl) 
library(XML) 
curl = getCurlHandle() 
curlSetOpt(cookiefile="cookies.txt" 
      , curl=curl, followLocation = TRUE) 
pdfData <- getBinaryURL(appURL, curl = curl, .opts = list(cookie = "ADSCOPYRIGHT=YES")) 
writeBin(pdfData, "test2.pdf") 

Oto dłuższa wersja pokazano jego pracy

appURL <- "http://archaeologydataservice.ac.uk/archiveDS/archiveDownload?t=arch-1352-1/dissemination/pdf/Dyfed/GL44004.pdf" 
library(RCurl) 
library(XML) 
curl = getCurlHandle() 
curlSetOpt(cookiefile="cookies.txt" 
      , curl=curl, followLocation = TRUE) 
appData <- getURL(appURL, curl = curl) 

# get the necessary elements for the POST that is initiated when the ACCEPT button is pressed 

doc <- htmlParse(appData) 
appAttrs <- doc["//input", fun = xmlAttrs] 
postData <- lapply(appAttrs, function(x){data.frame(name = x[["name"]], value = x[["value"]] 
                , stringsAsFactors = FALSE)}) 
postData <- do.call(rbind, postData) 

# post your acceptance 
postURL <- "http://archaeologydataservice.ac.uk/myads/copyrights.jsf;jsessionid=" 
# get jsessionid 
jsessionid <- unlist(strsplit(getCurlInfo(curl)$cookielist[1], "\t"))[7] 

searchData <- postForm(paste0(postURL, jsessionid), curl = curl, 
         "j_id10" = "j_id10", 
         from = postData[postData$name == "from", "value"], 
         "javax.faces.ViewState" = postData[postData$name == "javax.faces.ViewState", "value"], 
         "j_id10:_idcl" = "j_id10:agreeButton" 
         , binary = TRUE 
) 
con <- file("test.pdf", open = "wb") 
writeBin(searchData, con) 
close(con) 


Pressing the ACCEPT button on the page you gave initiates a POST to "http://archaeologydataservice.ac.uk/myads/copyrights.jsf;jsessionid=......" via some javascript. 
This post then redirects to the page with the pdf having given some additional cookies. 

Checking our cookies we see: 

> getCurlInfo(curl)$cookielist 
[1] "archaeologydataservice.ac.uk\tFALSE\t/\tFALSE\t0\tJSESSIONID\t3d249e3d7c98ec35998e69e15d3e" 
[2] "archaeologydataservice.ac.uk\tFALSE\t/\tFALSE\t0\tSSOSESSIONID\t3d249e3d7c98ec35998e69e15d3e" 
[3] "archaeologydataservice.ac.uk\tFALSE\t/\tFALSE\t0\tADSCOPYRIGHT\tYES"   

so it would probably be sufficient to set that last cookie to start with (indicating we accept copyright)