【问题标题】:How to trigger a file download using R如何使用 R 触发文件下载
【发布时间】:2019-05-19 08:40:11
【问题描述】:

我正在尝试使用 R 在此站点上触发文件下载:http://www.regulomedb.org。基本上,在表单中输入一个 ID,例如 rs33914668,单击提交。然后在新页面,点击左下角的下载,触发文件下载。

我在其他帖子的帮助下尝试了 rvest。

library(httr)
library(rvest)
library(tidyverse)

pre_pg <- read_html("http://www.regulomedb.org")
POST(
  url = "http://www.regulomedb.org", 
  body = list(
    data = "rs33914668"
  ),
  encode =  "form"
  )
) -> res
pg <- content(res, as="parsed")

通过检查 pg,我想我仍然在第一页,而不是 http://www.regulomedb.org/results。 (除了逐行阅读之外,我不知道如何检查 pg 列表)。所以,我无法到达下载按钮。我不知道为什么它不能跳到下一页。

通过从其他一些帖子中学习,我设法在不使用 rvest 的情况下下载了文件。

library(httr)
library(rvest)
library(RCurl)

session <- html_session("http://www.regulomedb.org")
form <- html_form(session)[[1]]
filledform <- set_values(form, `data` = "rs33914668")

session2 <- submit_form(session, filledform)
form2 <- html_form(session2)[[1]]
filledform2 <- set_values(form2)

thesid <- filledform2[["fields"]][["sid"]]$value
theurl <- paste0('http://www.regulomedb.org/download/',thesid)
download.file(theurl,destfile="test.bed",method="libcurl")

在fillform2中,我找到了sid。使用 www.regulomedb.org/download/:sid,我可以下载该文件。

我是 html 甚至 R 的新手,甚至不知道 sid 是什么。虽然我做到了,但我对编码并不满意。所以,我希望一些有经验的用户可以提供更好的、替代的解决方案,或者改进我目前的解决方案。另外,POST/rvest 方法有什么问题?

【问题讨论】:

  • 查看页面上的代码,如果您将预期的值名称与列表中的名称匹配,那么简单的 POST 似乎应该可以工作。你检查过这些例子吗?表单部分为:&lt;form action="/results" enctype="multipart/form-data" method="POST"&gt; &lt;textarea id="input_text" name="data" rows="12"&gt; &lt;/textarea&gt; &lt;input type="submit" value="Submit" /&gt; &lt;/form&gt;&lt;/div&gt;
  • 元素的名字是data。 POST 后,网页的元素表明它仍然是第一页。我尝试了不同的示例,但问题仍然存在。看到有人用了add_header,不知道是不是这个问题的原因。
  • sid 是一个会话 ID(并作为 cookie 发送到您的浏览器)。使用str(session2) 查看整个会话结果。它显示了当textarea 填充有rs33914668 并按下提交按钮时访问呈现给用户的下一页的方法。它有许多列表元素,其中之一是$ url : chr "http://www.regulomedb.org/results"。我通过将data=c(submit="submit") 添加到 submit_form 参数来使 POST 工作。您现在需要查看该新网页并决定您希望在代码中模拟的众多可能操作中的哪一个。

标签: html r web-crawler rvest


【解决方案1】:
url<-"http://www.regulomedb.org/"
library(rvest)
page<-html_session(url)

download_page<-rvest:::request_POST(page,url="http://www.regulomedb.org/results",
                                    body=list("data"="rs33914668"),
                                    encode = 'form')

#This is a unique id on generated based on your query
sid<-html_nodes(download_page,css='#download > input[type="hidden"]:nth-child(8)') %>% html_attr('value')

#This is a UNIX time
download_token<-as.numeric(as.POSIXct(Sys.time()))

download_page1<-rvest:::request_POST(download_page,url="http://www.regulomedb.org/download",
                                    body=list("format"="bed",
                                              "sid"=sid,
                                              "download_token_value_id"=download_token ),
                                    encode = 'form')
writeBin(download_page1$response$content, "regulomedb_result.bed")

【讨论】:

  • 用“但是...”表示赞成。这看起来像是一个潜在有用的响应,但它只是代码。 SO 上不推荐使用纯代码答案,因此我建议您解释诸如如何选择论点以及为什么决定使用 R Sys.time-value 作为“download_token”等问题。
  • 道歉。我徒劳地复制并粘贴了代码。当我分析请求时,有一个类似于 UNIX 时间的下载令牌,我将其转换为正常时间并确认它是 UNIX 时间(我认为在该字段“download_token”中发送任何时间都没有关系跨度>
  • 非常感谢!你解决了这个问题,并给了我另一个我可以学习的解决方案。干得好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2010-12-03
  • 2020-07-30
相关资源
最近更新 更多