如何强制 For loop() 或 lapply() 在 R 中运行并显示错误消息



当我使用 for 循环或函数 lapply 时,在此代码上,我收到以下错误

"Error in get_entrypoint (debug_port):
Cannot connect R to Chrome. Please retry. "

library(rvest)
library(xml2) #pull html data
library(selectr) #for xpath element
url_stackoverflow_rmarkdown <- 
'https://stackoverflow.com/questions/tagged/r-markdown?tab=votes&pagesize=50'
web_page <- read_html(url_stackoverflow_rmarkdown)
questions_per_page <- html_text(html_nodes(web_page, ".page-numbers.current"))[1]
link_questions <- html_attr(html_nodes(web_page, ".question-hyperlink")[1:questions_per_page], 
"href")
setwd("~/WebScraping_chrome_print_to_pdf") 
for (i in 1:length(link_questions)) {
question_to_pdf <- paste0("https://stackoverflow.com",
link_questions[i])
pagedown::chrome_print(question_to_pdf) 
}

是否可以构建for loop()或使用lapply来重复代码中断的地方?也就是说,从最后一个i值开始而不破坏代码?

非常感谢

我编辑了@Rui巴拉达斯tryCatch()的想法。 您可以尝试执行以下操作。IsValues将获得链接值或错误is。

IsValues <- list()
for (i in 1:length(link_questions)) {
question_to_pdf <- paste0("https://stackoverflow.com",
link_questions[i])
IsValues[[i]] <- tryCatch(
{
message(paste("Converting", i))
pagedown::chrome_print(question_to_pdf)
},
error=function(cond) {
message(paste("Cannot convert", i))
# Choose a return value in case of error
return(i)
}) 
}

比,你可以重新绑定你的值并提取坏i

do.call(rbind, IsValues)[!grepl("\.pdf$", do.call(rbind, IsValues))]
[1] "3"  "5"  "19" "31"

您可以在此答案中阅读有关tryCatch()的更多信息。

根据您的示例,您似乎有两个错误需要应对。第一个错误是您在问题中提到的错误。这也是最常见的错误:

get_entrypoint (debug_port( 中的错误:无法将 R 连接到 Chrome。请重试。

当 HTML 中有返回 404 的链接时,会出现第二个错误:

无法生成输出。原因:无法打开 https://lh3.googleusercontent.com/-bwcos_zylKg/AAAAAAAAAAI/AAAAAAAAAAA/AAnnY7o18NuEdWnDEck_qPpn-lu21VTdfw/mo/photo.jpg?sz=32(HTTP 状态代码:404(

第一个错误中的关键词是"请重试"。据我所知,chrome_print有时在连接到Chrome时会遇到问题。这似乎是相当随机的,即一次运行中失败的连接在下一次运行中会很好,反之亦然。解决此问题的最简单方法是继续尝试,直到连接为止。

我无法为第二个错误想出任何解决方法。但是,它似乎并不经常出现,因此仅记录它并跳到下一个 URL 可能是有意义的。

使用以下代码,我可以打印 48 页(共 50 页(。我唯一无法上班的两个问题有我上面描述的 404 问题。请注意,我使用purrr::safely来捕获错误。Base R 的tryCatch也可以正常工作,但我发现safely更方便一些。也就是说,归根结底,这实际上只是一个偏好问题。

另请注意,我已经通过在 for 循环中使用repeat来处理连接错误。R 将继续尝试连接到 Chrome 并打印,直到成功或弹出其他错误。我不需要它,但您可能希望包含一个计数器来设置连接尝试次数的上限阈值:

quest_urls <- paste0("https://stackoverflow.com", link_questions)
errors <- NULL
safe_print <- purrr::safely(pagedown::chrome_print)
for (qurl in quest_urls){
repeat {
output <- safe_print(qurl)
if (is.null(output$error)) break
else if (grepl("retry", output$error$message)) next
else {errors <- c(errors, `names<-`(output$error$message, qurl)); break}
}
}

最新更新