我正在尝试抓取一个需要按按钮才能填充表格的网页。我可以对某些按钮实现此目的,但不能对其他按钮实现此目的。我正在尝试使用
rvest
创建可重现的管道,并且我目前对使用 RSelenium
的解决方案不感兴趣。
该表格来自以下网站:https://osf.io/search?resourceType=Registration%2CRegistrationComponent
单击“创建日期”下拉列表后,表格将填充在左侧边距中。
这是我到目前为止所拥有的:
library(rvest)
url <- "https://osf.io/search?resourceType=Registration%2CRegistrationComponent"
pr_sess <- read_html_live(url)
pr_sess$view()
pr_sess$click("#dateCreated-09883579765073658")
出现以下错误:“onRejected(reason) 中的错误:代码:-32000 消息:节点没有布局对象”
但是,我可以模拟某些元素的点击。例如,我可以使用以下代码模拟单击“创建的数据”正上方的“创建者”下拉列表:
pr_sess$click("#first-filter-08170256355625345")
我相信这是因为我在css中为“Creator”使用了定义的ID,但“Datacreated”没有这样的ID。需要明确的是,我正在寻找的解决方案应该涉及使用
pr_sess$click()
并且期望的结果是切换下拉菜单。
编辑: 之前似乎对我有用的代码 (
pr_sess$click("#first-filter-08170256355625345")
),在重新启动我的 R 会话后不再起作用。看起来 ID 的第一部分总是相同的(即#first-filter-),但数字总是不同的。我开始质疑是否真的有办法使这个过程可重复。
正如您正确指出的那样,使用唯一的 HTML 标识符通常更容易。所有 HTML 元素都有特定的属性。拿起想要点击的按钮:
<button class="_Button_6kisxq _FakeLink_6kisxq _facet-expand-button_13c61c" data-analytics-name="Filter facet toggle Date created" data-test-filter-facet-toggle="Date created" aria-controls="dateCreated-08686056605854187" title="Date created" type="button">
<span>Date created</span>
<svg class="svg-inline--fa fa-caret-down" data-prefix="fas" data-icon="caret-down" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path>
</svg>
</button>
属性是:
class="_Button_6kisxq _FakeLink_6kisxq _facet-expand-button_13c61c" data-analytics-name="Filter facet toggle Date created" data-test-filter-facet-toggle="Date created" aria-controls="dateCreated-08686056605854187"
让我们点击
data-test-filter-facet-toggle='Date created'
单击“数据创建过滤器”下拉列表!
顺便说一句。您可以通过单击右上角的小箭头图标然后选择按钮元素来自行执行此操作:
终于可以实现稍后点击按钮了。我们需要等待元素出现,因为网站不会立即加载。然后,您甚至可以导出 ul-list,它接下来会选择任何过滤器值...
代码:
library(rvest)
library(chromote)
library(purrr)
library(tibble)
# Start a Chromote session
b <- ChromoteSession$new()
url <- "https://osf.io/search?resourceType=Registration%2CRegistrationComponent"
pr_sess <- read_html_live(url)
pr_sess$view()
# Click the "Date created" dropdown dynamically
# Step 2: Wait for the button to load and click it
timeout <- 10 # Maximum wait time in seconds
button <- NULL
start_time <- Sys.time()
while (is.null(button) && as.numeric(Sys.time() - start_time) < timeout) {
button <- tryCatch(
pr_sess %>% html_element("[data-test-filter-facet-toggle='Date created']"),
error = function(e) NULL
)
Sys.sleep(0.5) # Check every 0.5 seconds
}
if (is.null(button)) {
stop("Button did not appear within the timeout period.")
}
# Click the "Date created" dropdown
pr_sess$click("[data-test-filter-facet-toggle='Date created']")
# Step 3: Wait for the dropdown to load
Sys.sleep(2) # Adjust based on load time
# Step 4: Extract the list items of the ul list below the filter
facet_list <- pr_sess %>%
html_elements("ul._facet-list_13c61c li._facet-value_13c61c")
# Step 5: Parse the extracted items into a data frame
facet_data <- facet_list %>%
map_df(~ {
year <- .x %>%
html_element("button") %>%
html_text2() %>%
as.character()
count <- .x %>%
html_element("span._facet-count_13c61c") %>%
html_text2() %>%
as.integer()
tibble(year = year, count = count)
})
# Print the extracted data
print(facet_data)
# click on any of the list values, filter with e.g. pr_sess$click("[data-test-filter-facet-value = '2024']")
这将打印可用的创建日期列表:
> # Print the extracted data
> print(facet_data)
# A tibble: 14 × 2
year count
<chr> <int>
1 2024 31020
2 2023 31001
3 2022 28099
4 2021 25604
5 2020 24456
6 2019 17142
7 2018 13833
8 2017 8751
9 2016 5688
10 2015 3314
11 2014 954
12 2013 717
13 2012 91
14 2011 2