迭代 rvest scrape 函数给出:"Error in open.connection(x, "rb") : Timeout was reached"
Iterating rvest scrape function gives: "Error in open.connection(x, "rb") : Timeout was reached"
我正在使用 "rvest" 包抓取 this website。当我重复我的函数太多次时,我得到 "Error in open.connection(x, "rb") : Timeout was reached"。我搜索过类似的问题,但答案似乎是死胡同。我怀疑它是服务器端的,并且该网站对我可以访问该页面的次数有内置限制。如何研究这个假设?
代码: 我有底层网页的链接,想用从关联网页中提取的信息构建一个数据框。我已经稍微简化了我的抓取功能,因为问题仍然存在于更简单的功能中:
scrape_test = function(link) {
slit <- str_split(link, "/") %>%
unlist()
id <- slit[5]
sem <- slit[6]
name <- link %>%
read_html(encoding = "UTF-8") %>%
html_nodes("h2") %>%
html_text() %>%
str_replace_all("\r\n", "") %>%
str_trim()
return(data.frame(id, sem, name))
}
我使用 purrr-package map_df() 来迭代函数:
test.data = links %>%
map_df(scrape_test)
现在,如果我仅使用 50 个链接迭代该函数,我不会收到任何错误。但是当我增加链接数量时,我遇到了前面提到的错误。此外,我收到以下警告:
- "In bind_rows_(x, .id) : Unequal factor levels: coercing to character"
- "closing unused connection 4 (link)"
编辑: 下面制作链接对象的代码可用于重现我的结果:
links <- c(rep("http://karakterstatistik.stads.ku.dk/Histogram/NMAK13032E/Winter-2013/B2", 100))
对于大型抓取任务,我通常会执行 for 循环,这有助于故障排除。为您的输出创建一个空列表:
d <- vector("list", length(links))
这里我用一个 tryCatch
块做一个 for 循环,这样如果输出是错误的,我们等待几秒钟然后重试。如果我们在五次尝试后仍然遇到错误,我们还包括一个 counter
移动到下一个 link 。此外,我们有 if (!(links[i] %in% names(d)))
这样如果我们必须打破循环,我们可以跳过我们在重新启动循环时已经抓取的 links。
for (i in seq_along(links)) {
if (!(links[i] %in% names(d))) {
cat(paste("Doing", links[i], "..."))
ok <- FALSE
counter <- 0
while (ok == FALSE & counter <= 5) {
counter <- counter + 1
out <- tryCatch({
scrape_test(links[i])
},
error = function(e) {
Sys.sleep(2)
e
}
)
if ("error" %in% class(out)) {
cat(".")
} else {
ok <- TRUE
cat(" Done.")
}
}
cat("\n")
d[[i]] <- out
names(d)[i] <- links[i]
}
}
我正在使用 "rvest" 包抓取 this website。当我重复我的函数太多次时,我得到 "Error in open.connection(x, "rb") : Timeout was reached"。我搜索过类似的问题,但答案似乎是死胡同。我怀疑它是服务器端的,并且该网站对我可以访问该页面的次数有内置限制。如何研究这个假设?
代码: 我有底层网页的链接,想用从关联网页中提取的信息构建一个数据框。我已经稍微简化了我的抓取功能,因为问题仍然存在于更简单的功能中:
scrape_test = function(link) {
slit <- str_split(link, "/") %>%
unlist()
id <- slit[5]
sem <- slit[6]
name <- link %>%
read_html(encoding = "UTF-8") %>%
html_nodes("h2") %>%
html_text() %>%
str_replace_all("\r\n", "") %>%
str_trim()
return(data.frame(id, sem, name))
}
我使用 purrr-package map_df() 来迭代函数:
test.data = links %>%
map_df(scrape_test)
现在,如果我仅使用 50 个链接迭代该函数,我不会收到任何错误。但是当我增加链接数量时,我遇到了前面提到的错误。此外,我收到以下警告:
- "In bind_rows_(x, .id) : Unequal factor levels: coercing to character"
- "closing unused connection 4 (link)"
编辑: 下面制作链接对象的代码可用于重现我的结果:
links <- c(rep("http://karakterstatistik.stads.ku.dk/Histogram/NMAK13032E/Winter-2013/B2", 100))
对于大型抓取任务,我通常会执行 for 循环,这有助于故障排除。为您的输出创建一个空列表:
d <- vector("list", length(links))
这里我用一个 tryCatch
块做一个 for 循环,这样如果输出是错误的,我们等待几秒钟然后重试。如果我们在五次尝试后仍然遇到错误,我们还包括一个 counter
移动到下一个 link 。此外,我们有 if (!(links[i] %in% names(d)))
这样如果我们必须打破循环,我们可以跳过我们在重新启动循环时已经抓取的 links。
for (i in seq_along(links)) {
if (!(links[i] %in% names(d))) {
cat(paste("Doing", links[i], "..."))
ok <- FALSE
counter <- 0
while (ok == FALSE & counter <= 5) {
counter <- counter + 1
out <- tryCatch({
scrape_test(links[i])
},
error = function(e) {
Sys.sleep(2)
e
}
)
if ("error" %in% class(out)) {
cat(".")
} else {
ok <- TRUE
cat(" Done.")
}
}
cat("\n")
d[[i]] <- out
names(d)[i] <- links[i]
}
}