使用 rvest 下载需要从网站登录的压缩文件 (morphosource) HTML
Downloading a zipped file requiring login from a website (morphosource) HTML using rvest
我知道Whosebug上也有类似的问题,但是翻了翻还是没有找到下载我需要的文件的方法。我有一个 http 网址列表。当我登录到感兴趣的网站 (MorphoSource) 并在浏览器中输入地址时,它会自动下载一个压缩文件夹。我需要从 R 中执行此操作,以便我可以循环下载其中的许多文件夹。
这是一个这样的 http 地址(尽管没有登录就不会发生任何事情):"http://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/119/media_file_id/52"
我已经使用下面的代码取得了最大的进步,但我仍然收到一条错误消息,提示我 Submitting with 'NULL'
并且当我查看下载的文件时,它大约为 8kb,而它应该超过 50,000kb
library(rvest)
login<-"https://www.morphosource.org/LoginReg/form"
pgsession<-html_session(login)
pgform<-html_form(pgsession)[[2]]
filled_form<-set_values(pgform, username="TestingPackage@gmail.com", password="testingpackage")
submit_form(pgsession, filled_form)
download.file("http://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/119/media_file_id/52", "testfile")
我是 R 的新手,对通过 R 中的网址下载压缩文件夹的想法完全陌生,因此非常感谢您的帮助。
我们只需要为您做一些会话管理:
morphosource_dl <- function(media_id, # if end of URL is /media_id/119/media_file_id/52 then this is 119
media_file_id, # if end of URL is /media_id/119/media_file_id/52 then this is 52
overwrite = TRUE, # overwrite file if it already exists?
.progress = TRUE, # show a download progress bar?
username = Sys.getenv("MORPHOSOURCE_EMAIL"), # pass in here or store in ~/.Renviron
password = Sys.getenv("MORPHOSOURCE_PASSWORD")) { # pass in here or store in ~/.Renviron
suppressPackageStartupMessages({
library(httr, warn.conflicts = FALSE, quietly = TRUE, verbose = FALSE)
library(rvest, warn.conflicts = FALSE, quietly = TRUE, verbose = FALSE)
})
# Start a sessiion
res <- httr::GET(url = "https://www.morphosource.org/Splash/Index")
# login
httr::POST(
url = "https://www.morphosource.org/LoginReg/login",
httr::add_headers(
Referer = "https://www.morphosource.org/LoginReg/form"
),
body = list(
username = username,
password = password
),
encode = "form"
) -> res
# if successful
if (length(html_nodes(httr:::content(res), xpath=".//*[contains(., 'You have been logged in')]")) > 0) {
httr::stop_for_status(res) # make sure it really was successful
# do this to get filename
httr::HEAD(
url = sprintf(
"https://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/%s/media_file_id/%s",
media_id, media_file_id
)
) -> res
fil <- gsub("^.*filename=", "", res$headers["content-disposition"])
httr::GET(
url = "https://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/119/media_file_id/52",
httr::write_disk(fil, overwrite = overwrite),
if (.progress) httr::progress()
) -> res
if (.progress) cat("\n")
return(fil)
} else {
message("Error logging in")
httr::stop_for_status(res)
}
}
你的 URL 是 http://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/119/media_file_id/52
(实际上是 https://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/119/media_file_id/52
,这是一个重要的区别)。
这意味着 "media id" 是 119
而 "media file id" 是 52
。
如果您做对了并在您的 ~/.Renviron
中输入:
MORPHOSOURCE_EMAIL=me@example.com
MORPHOSOURCE_PASSWORD=aBetterP@s$w0rDThanThis
并刷新你的 R 会话,然后你可以这样做:
morphosource_dl("119", "52")
## Downloading: ... MB
## [1] "Morphosource_AMNH-M-100635_M119-52.zip"
将为您下载。
否则你可以这样做:
morphosource_dl(
media_id = "119",
media_file_id = "52",
username = "donotdothis@example.com",
password = "embeddingCredentialsInScriptsIsNotTooBright"
)
它仍然会下载它。
在这两种情况下,它都是 returns 文件的名称。
您可以使用 overwrite
参数控制是否覆盖文件(默认为 TRUE
),是否需要进度条(默认为 TRUE
)使用 .progress
.
您遇到的问题是 download.file()
对 rvest
的基础一无所知,即 curl
和 httr
(以及 xml2
)。因此 download.file()
无法获取您的 rvest
调用生成的会话 cookie。您可能只是调用了 httr::GET()
和下载 link 的 https
版本,并在您开始使用后在其中使用 httr::write_disk()
,但是上面的函数封装了这一切都变成了一个动作,并且还找出了文件名(你必须手动设置)之前。
我们只是做了 "long way" 并模仿了浏览器对 GET
和 POST
所做的:
我知道Whosebug上也有类似的问题,但是翻了翻还是没有找到下载我需要的文件的方法。我有一个 http 网址列表。当我登录到感兴趣的网站 (MorphoSource) 并在浏览器中输入地址时,它会自动下载一个压缩文件夹。我需要从 R 中执行此操作,以便我可以循环下载其中的许多文件夹。
这是一个这样的 http 地址(尽管没有登录就不会发生任何事情):"http://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/119/media_file_id/52"
我已经使用下面的代码取得了最大的进步,但我仍然收到一条错误消息,提示我 Submitting with 'NULL'
并且当我查看下载的文件时,它大约为 8kb,而它应该超过 50,000kb
library(rvest)
login<-"https://www.morphosource.org/LoginReg/form"
pgsession<-html_session(login)
pgform<-html_form(pgsession)[[2]]
filled_form<-set_values(pgform, username="TestingPackage@gmail.com", password="testingpackage")
submit_form(pgsession, filled_form)
download.file("http://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/119/media_file_id/52", "testfile")
我是 R 的新手,对通过 R 中的网址下载压缩文件夹的想法完全陌生,因此非常感谢您的帮助。
我们只需要为您做一些会话管理:
morphosource_dl <- function(media_id, # if end of URL is /media_id/119/media_file_id/52 then this is 119
media_file_id, # if end of URL is /media_id/119/media_file_id/52 then this is 52
overwrite = TRUE, # overwrite file if it already exists?
.progress = TRUE, # show a download progress bar?
username = Sys.getenv("MORPHOSOURCE_EMAIL"), # pass in here or store in ~/.Renviron
password = Sys.getenv("MORPHOSOURCE_PASSWORD")) { # pass in here or store in ~/.Renviron
suppressPackageStartupMessages({
library(httr, warn.conflicts = FALSE, quietly = TRUE, verbose = FALSE)
library(rvest, warn.conflicts = FALSE, quietly = TRUE, verbose = FALSE)
})
# Start a sessiion
res <- httr::GET(url = "https://www.morphosource.org/Splash/Index")
# login
httr::POST(
url = "https://www.morphosource.org/LoginReg/login",
httr::add_headers(
Referer = "https://www.morphosource.org/LoginReg/form"
),
body = list(
username = username,
password = password
),
encode = "form"
) -> res
# if successful
if (length(html_nodes(httr:::content(res), xpath=".//*[contains(., 'You have been logged in')]")) > 0) {
httr::stop_for_status(res) # make sure it really was successful
# do this to get filename
httr::HEAD(
url = sprintf(
"https://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/%s/media_file_id/%s",
media_id, media_file_id
)
) -> res
fil <- gsub("^.*filename=", "", res$headers["content-disposition"])
httr::GET(
url = "https://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/119/media_file_id/52",
httr::write_disk(fil, overwrite = overwrite),
if (.progress) httr::progress()
) -> res
if (.progress) cat("\n")
return(fil)
} else {
message("Error logging in")
httr::stop_for_status(res)
}
}
你的 URL 是 http://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/119/media_file_id/52
(实际上是 https://www.morphosource.org/index.php/Detail/MediaDetail/DownloadMedia/media_id/119/media_file_id/52
,这是一个重要的区别)。
这意味着 "media id" 是 119
而 "media file id" 是 52
。
如果您做对了并在您的 ~/.Renviron
中输入:
MORPHOSOURCE_EMAIL=me@example.com
MORPHOSOURCE_PASSWORD=aBetterP@s$w0rDThanThis
并刷新你的 R 会话,然后你可以这样做:
morphosource_dl("119", "52")
## Downloading: ... MB
## [1] "Morphosource_AMNH-M-100635_M119-52.zip"
将为您下载。
否则你可以这样做:
morphosource_dl(
media_id = "119",
media_file_id = "52",
username = "donotdothis@example.com",
password = "embeddingCredentialsInScriptsIsNotTooBright"
)
它仍然会下载它。
在这两种情况下,它都是 returns 文件的名称。
您可以使用 overwrite
参数控制是否覆盖文件(默认为 TRUE
),是否需要进度条(默认为 TRUE
)使用 .progress
.
您遇到的问题是 download.file()
对 rvest
的基础一无所知,即 curl
和 httr
(以及 xml2
)。因此 download.file()
无法获取您的 rvest
调用生成的会话 cookie。您可能只是调用了 httr::GET()
和下载 link 的 https
版本,并在您开始使用后在其中使用 httr::write_disk()
,但是上面的函数封装了这一切都变成了一个动作,并且还找出了文件名(你必须手动设置)之前。
我们只是做了 "long way" 并模仿了浏览器对 GET
和 POST
所做的: