rdownloadrcurlrvesthttr

R: Download image using rvest


I'm attempting to download a png image from a secure site through R.

To access the secure site I used Rvest which worked well.

So far I've extracted the URL for the png image.

How can I download the image of this link using rvest?

Functions outside of the rvest function return errors due to not having permission.

Current attempts

library(rvest)
uastring <- "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"
session <- html_session("https://url.png", user_agent(uastring))
form <- html_form(session)[[1]]
form <- set_values(form, username = "***", password="***", cookie_checkbox= TRUE)
session<-submit_form(session, form)
session2<-jump_to(session, "https://url.png")

## Status 200 using rvest, sucessfully accsessed page.    
session 
<session> https://url.png
  Status: 200
  Type:   image/png
  Size:   438935

## Using download.file returns status 403, page unable to open.
download.file("https://url.png", destfile = "t.png")
    cannot open: HTTP status was '403 Forbidden'

Have tried readPNG and download.file on the url, both of which failed due to not having permission to download from a authenticated secure site (error: 403), hence why I used rvest in the first place.


Solution

  • Here's one example to download the R logo into the current directory.

    library(rvest)
    url <- "https://www.r-project.org"
    imgsrc <- read_html(url) %>%
      html_node(xpath = '//*/img') %>%
      html_attr('src')
    imgsrc
    # [1] "/Rlogo.png"
    
    # side-effect!
    download.file(paste0(url, imgsrc), destfile = basename(imgsrc))
    

    EDIT

    Since authentication is involved, Austin's suggestion of using a session is certainly required. Try this:

    library(rvest)
    library(httr)
    sess <- html_session(url)
    imgsrc <- sess %>%
      read_html() %>%
      html_node(xpath = '//*/img') %>%
      html_attr('src')
    img <- jump_to(sess, paste0(url, imgsrc))
    
    # side-effect!
    writeBin(img$response$content, basename(imgsrc))