当页面上没有嵌入特定文件时,如何使用R从网页下载文件

时间:2019-05-29 18:22:55

标签: html r web-scraping

当在R中没有使用download.file()上传特定文件时,是否有任何可能的解决方案可以从任何网站提取文件。

我有这个网址

https://www.fangraphs.com/leaders.aspx?pos=all&stats=bat&lg=all&qual=y&type=8&season=2016&month=0&season1=2016&ind=0

有一个将csv文件导出到我的工作目录的链接,但是当我右键单击网页上的导出数据超链接并选择链接地址时, 变成以下脚本

javascript:__doPostBack('LeaderBoard1$cmdCSV','') 

而不是使我可以访问csv文件的URL。

是否有解决此问题的解决方案。

1 个答案:

答案 0 :(得分:0)

您可以将RSelenium用于此类工作。下面的脚本对我来说完全一样,并且对文本进行了一些较小的修改也对您有用。该解决方案使用两个软件包:RSelenium使Chrome自动运行,以及here选择活动目录。

library(RSelenium)
library(here)

这是您提供的网址:

url <- paste0(
  "https://www.fangraphs.com/leaders.aspx",
  "?pos=all",
  "&stats=bat",
  "&lg=all",
  "&qual=y",
  "&type=8",
  "&season=2016",
  "&month=0",
  "&season1=2016",
  "&ind=0"
)

这是下载按钮的ID。右键单击Chrome中的按钮,然后单击“检查”,即可找到它。

button_id <- "LeaderBoard1_cmdCSV"

我们将使Chrome自动下载文件,并且它将转到您的默认下载位置。在脚本末尾,我们想将其移动到当前目录。因此,首先让我们设置文件名称(每个fangraphs.com)和您的下载位置(您应根据需要编辑):

filename <- "FanGraphs Leaderboard.csv"
download_location <- file.path(Sys.getenv("USERPROFILE"), "Downloads")

现在,您将要启动浏览器会话。我使用的是Chrome,我可以指定此特定的Chrome版本(使用chromever参数)。 YMMV;检查为您启动浏览器会话的最佳方法。

rsDriver对象包含两个部分:服务器和浏览器客户端。大多数魔术都发生在浏览器客户端中。

driver <- rsDriver(
  browser = "chrome",
  chromever = "74.0.3729.6"
)
server <- driver$server
browser <- driver$client

使用浏览器客户端,导航到页面,然后单击该按钮。

操作前的快速注意事项:RSelenium可能会开始寻找该按钮并尝试在没有任何单击之前单击它。因此,我添加了几行来观察按钮的显示,然后在按钮出现后单击它。

buttons <- list()
browser$navigate(url)
while (length(buttons) == 0) {
  buttons <- browser$findElements(button_id, using = "id")
}
buttons[[1]]$clickElement()

然后等待文件显示在您的下载文件夹中,然后将其移动到当前项目目录:

while (!file.exists(file.path(download_location, filename))) {
  Sys.sleep(0.1)
}
file.rename(file.path(download_location, filename), here(filename))

最后,请务必清理服务器和浏览器客户端,否则RSelenium会变得古怪。

browser$close()
server$stop()

然后您就走上了快乐的路!


假设这是另一种情况,并且您没有要使用的ID。 ID之所以出色,是因为ID可以唯一地标识元素,并且使用它们几乎不需要了解网站语言。但是正如您在评论中指出的那样,并非所有HTML元素都具有ID!

在我指定using = "id"的位置上,您还有很多其他选择:

  • using = "xpath"
  • using = "css selector"
  • using = "name"
  • using = "tag name"
  • using = "class name"
  • using = "link text"
  • using = "partial link text"

这些为您提供了 ton 个选项,实际上可以让您识别页面上的所有内容。 findElements将始终返回列表。如果找不到任何内容,则该列表的长度为零。如果它找到多个元素,您将全部获得。

特别是XPath和CSS选择器超级通用。而且您可以在不真正知道自己在做什么的情况下找到它们。让我们看一下该页面上的“登录”按钮的示例,该按钮实际上没有ID。

通过漂亮的Control + Shift + J在Chrome中启动以获取开发者控制台。在显示的面板的左上角,有一个用于选择元素的小图标:

enter image description here

单击它,然后单击所需的元素:

enter image description here

这将在“元素”面板中将其拉高(突出显示)。右键单击突出显示的行,然后单击“复制选择器”。如果要使用XPath,也可以单击“复制XPath”。

enter image description here

这为您提供了代码!

buttons <- browser$findElements(
  "#linkAccount > div > div.label-account",
  using = "css selector"
)
buttons[[1]]$clickElement()

景气。