2016-01-06 5 views
8

Ich bleibe bei Cookies stecken, wenn ich versuche, ein PDF herunterzuladen.Verwenden von R zum Akzeptieren von Cookies zum Herunterladen einer PDF-Datei

Zum Beispiel, wenn ich ein DOI für ein PDF-Dokument auf der Archäologie Data Service habe, wird es zu this landing page mit einem embedded link in it to this pdf lösen, aber die wirklich Umleitungen an this anderen Link.

library(httr) wird die Auflösung des DOI behandeln und wir können die PDF-URL aus der Zielseite mit library(XML) extrahieren, aber ich bin bei der Beschaffung der PDF selbst fest.

Wenn ich dies tun:

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

dann ich eine HTML-Datei erhalten, die die gleiche wie http://archaeologydataservice.ac.uk/myads/ ist

Der Versuch, die Antwort auf How to use R to download a zipped file from a SSL page that requires cookies führt mich dazu:

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") 

Aber nach den POST und GET Funktionen bekomme ich einfach den HTML-Code der gleichen Cookie-Seite, die ich mitbekommen habe:

> 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... 
... 

bei http://archaeologydataservice.ac.uk/about/Cookies Blick scheint es, dass die Cookie-Situation an dieser Stelle ist kompliziert. Scheint, dass diese Art von Cookie-Komplexität für britische Datenanbieter nicht ungewöhnlich ist: automating the login to the uk data service website in R with RCurl or httr

Wie kann ich mit R die Cookies auf dieser Website umgehen?

Antwort

6

Ihre Bitte auf rOpenSci wurde gehört!

Es gibt viele Javascript zwischen diesen Seiten, die es etwas nervig macht, über httr + rvest zu entziffern versuchen. Versuchen Sie RSelenium. Dies funktionierte unter OS X 10.11.2, R 3.2.3 & Firefox geladen.

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")) 

Warten Sie, bis der Download abgeschlossen ist. Die R-Konsole ist während des Herunterladens nicht beschäftigt, daher ist es einfach, die Sitzung versehentlich zu schließen, bevor der Download abgeschlossen ist.

# close the session 
dr$close() 
+0

Probieren Sie Ubuntu 14.04, R 3.2.3 und Firefox aus. 'dr $ open()' meldet '[1]" Mit remoten Server verbinden " Nicht definierter Fehler in RCurl call.Error in queryRD (paste0 (serverURL,"/Sitzung ")," POST ", qdata = toJSON (serverOpts)): ' –

+1

Dies war immer meine größte Nit, um mit Selen im Allgemeinen zu picken (nicht unbedingt das R pkg). Konsistenz zwischen Windows, OS X & * nix ist so schwierig.Hoffentlich können die Leute dazu beitragen (all meine * nix-Systeme sind sehr dünn konfigurierte kopflose Server-y-Dinge und ich darf nicht versuchen, den phantomjs-Treiber heute Abend zu meistern :-) – hrbrmstr

+2

OK, gefunden, wie man es an meiner Arbeit macht Computer. Ich musste den Selenal Standalone Server zuerst manuell mit 'java -jar selen-server-standalone-2.48.0.jar' starten. Dann kann ich mich verbinden. –

3

Diese Antwort kam von John Harrison per E-Mail, auf seine Bitte hier gepostet:

Dies ermöglicht Ihnen, die PDF-Datei herunterladen:

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") 

Hier ist eine längere Version zeigt seine Arbeits

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) 
Verwandte Themen