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

1 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
Run Code Online (Sandbox Code Playgroud)

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

javascript:__doPostBack('LeaderBoard1$cmdCSV','') 
Run Code Online (Sandbox Code Playgroud)

而不是让我访问 csv 文件的 url。

有没有办法解决这个问题。

Ben*_*min 5

您可以RSelenium用于此类作业。下面的脚本完全适用于我,它也适用于您,并在文本中进行了小的编辑。该解决方案使用两个包:RSelenium自动化 Chrome 和here选择您的活动目录。

library(RSelenium)
library(here)
Run Code Online (Sandbox Code Playgroud)

这是您提供的网址:

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"
)
Run Code Online (Sandbox Code Playgroud)

这是下载按钮的 ID。您可以通过右键单击 Chrome 中的按钮并点击“检查”来找到它。

button_id <- "LeaderBoard1_cmdCSV"
Run Code Online (Sandbox Code Playgroud)

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

filename <- "FanGraphs Leaderboard.csv"
download_location <- file.path(Sys.getenv("USERPROFILE"), "Downloads")
Run Code Online (Sandbox Code Playgroud)

现在您需要启动浏览器会话。我使用 Chrome,指定这个特定的 Chrome 版本(使用chromever参数)对我有用。YMMV; 检查为您启动浏览器会话的最佳方式。

一个rsDriver对象有两部分:服务器和浏览器客户端。大多数魔法发生在浏览器客户端。

driver <- rsDriver(
  browser = "chrome",
  chromever = "74.0.3729.6"
)
server <- driver$server
browser <- driver$client
Run Code Online (Sandbox Code Playgroud)

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

做之前的快速说明:RSelenium可能会开始寻找按钮并尝试在有任何可点击之前点击它。所以我添加了几行来观察按钮是否出现,然后在按钮出现后单击它。

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

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

while (!file.exists(file.path(download_location, filename))) {
  Sys.sleep(0.1)
}
file.rename(file.path(download_location, filename), here(filename))
Run Code Online (Sandbox Code Playgroud)

最后,始终清理您的服务器和浏览器客户端,否则RSelenium就会变得古怪。

browser$close()
server$stop()
Run Code Online (Sandbox Code Playgroud)

你正在快乐的路上!


请注意,您不会总是有要使用的元素 ID,这没关系。ID 很棒,因为它们唯一地标识了一个元素,并且使用它们几乎不需要了解网站语言。但是,如果您没有要使用的 ID,则在我指定的位置上方using = "id",您还有很多其他选择:

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

这些为您提供了大量选择,并真正让您可以识别页面上的任何内容。findElements将始终返回一个列表。如果找不到任何东西,该列表的长度将为零。如果它找到多个元素,您将获得所有元素。

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

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

在此处输入图片说明

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

在此处输入图片说明

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

在此处输入图片说明

这给了你你的代码!

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

繁荣。