当 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。
有没有办法解决这个问题。
您可以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)
繁荣。