【问题标题】:add new field to form with rvest使用 rvest 添加新字段以形成
【发布时间】:2023-11-20 17:29:01
【问题描述】:

我正在尝试使用 rvest 下载 [完整的] 动态扩展的 [holdings] 表,但收到 Unknown field names 错误。

s <- html_session("http://innovatoretfs.com/etf/?ticker=ffty")
f <- html_form(s)[[1]]
#the following line fails:
f.new <- set_values(f, `__EVENTTARGET` = "ctl00$BodyPlaceHolder$ViewHoldingsLinkButton")

##subsequent lines are not tested##
doc <- submit_form(s, f.new)
tabs <- xml_find_all(doc, "//table")
holdings <- html_table(tabs, fill = T, trim = T)[[5]]

我对 HTML/HTTP 不是很好,但从我可以追查到的情况来看,在我看来,扩展表格需要使用这个新字段值集回发表单

检查set_values 函数后,似乎它只允许为现有字段赋值。

有没有办法在rvest 下的表单中添加新字段?如果没有,是否有人知道我可以使用另一个包来获得此功能?

[已编辑] 非常明确地表明我需要动态扩展表的完整版本并添加预期的后续表提取代码

【问题讨论】:

  • 你是否想随着时间的推移刮掉 ETF 表? (10,000美元表的增长)
  • 你也可以尝试使用 RSelenium 来刮桌子
  • @papelr 没有。我正在尝试抓取 FULL 持股表
  • @papelr 感谢指向RSelenium 的指针。不幸的是,它看起来像是在一条无人维护的道路上
  • 我会采用下面的解决方案并提出另一个关于如何获得完整表的 SO 问题......但我也有 80% 的把握有人会告诉你走 RSelenium 路线跨度>

标签: r rvest


【解决方案1】:

令人厌恶,但工作可能会被清理,但会向项目提交问题,以便正确修复 add_values 类型功能

getInnovatorHoldings <- function() {
    s <- html_session("http://innovatoretfs.com/etf/?ticker=ffty")
    f <- html_form(s)[[1]]
    f.new <- add_values(f,
                            `__EVENTTARGET` = "ctl00$BodyPlaceHolder$ViewHoldingsLinkButton",
                            `__EVENTARGUMENT` = "",
                            `submit` = NULL)

    s <- submit_form(s, f.new, "submit")
    doc <- read_html(s)
    tabs <- xml_find_all(doc, "//table")
    holdings <- html_table(tabs, fill = T, trim = T)[[5]]
    return(holdings)
}

add_values <- function(form, ...) {
    new_values <- list(...)
    no_match <- which(!names(new_values) %in% names(form$fields))
    for (n in no_match) {
        if (names(new_values[n]) == "submit") {
            form$fields[[names(new_values[n])]] <- new_input(name = names(new_values[n]), type = "submit", value = NULL)
        } else {
            form$fields[[names(new_values[n])]] <- new_input(name = names(new_values[n]), type = "hidden", value = new_values[n][[1]])
        }
    }
    return(form)
}

new_input <- function(name, type, value, checked = NULL, disabled = NULL, readonly = NULL, required = F) {
    return(
        structure(
            list(name = name,
                type = type,
                value = value,
                checked = checked,
                disabled = disabled,
                readonly = readonly,
                required = required
                ),
            class = "input"
        )
    )
}

【讨论】:

  • 我希望有一个更简单的 RSelenium 修复程序......当它出现时会更新我的答案
  • *.com/questions/33885629/…借来的提交按钮解决方案
【解决方案2】:

答案:rvest

此解决方案有效,但仅返回表的前 10 行:

library(tidyverse)
library(rvest)

ffty_url <- "http://innovatoretfs.com/etf/?ticker=ffty"

ffty_table <- ffty_url %>%
  read_html %>%
  html_table(fill = T) %>% 
  .[[5]]

正在努力获取完整的表格,但使用 rvest 可能无法做到这一点,因为它是可扩展的。老实说不确定。


答案:RSelenium

您将不得不安装 RSelenium 和 docker,并且有多个教程。 但是下面的代码也只返回前十行,这让我livid

library(RSelenium)
library(rvest)

remDr <- remoteDriver(port = 4445L, remoteServerAddr = "localhost",
                  browserName = "chrome")
remDr$open()
remDr$navigate("http://innovatoretfs.com/etf/?ticker=ffty")
page <- read_html(remDr$getPageSource()[[1]])
table <- html_table(page, fill = TRUE, header = T)
table[[5]]

如果有人想扩展任一组代码,请...

【讨论】:

    最近更新 更多