R语言爬取网站遇连接耗尽错误,如何退出循环保留已爬数据?
解决curl连接耗尽+保住已爬取数据的方案
别急!你辛苦爬了一周的数据大概率能保住,先按下面的步骤来:
第一步:尝试中断循环并立即备份数据
如果你的R还能响应(比如控制台还能输入命令):
- Windows按
Ctrl+Break,Mac/Linux按Esc或者Ctrl+C强制中断循环。 - 中断成功后,立刻执行这条命令把已爬取的
GNR变量存到本地:
存完之后你就可以放心处理错误了,数据已经稳稳存在本地文件里。save(GNR, file = "已爬取数据备份.RData")
如果系统完全卡住,没法操作R:
- 先试试用系统的任务管理器(Windows)/活动监视器(Mac)找到R的进程,优先选“退出”而非“强制退出”——软退出大概率会让R先保存当前工作区再关闭,能最大程度保留数据。
- 如果只能强制结束进程,重启R后检查你的IDE(比如RStudio)有没有自动恢复工作区的功能:默认情况下RStudio会在退出时提示是否保存工作区,要是你之前开了自动保存,大概率能找回
GNR变量,找回后立刻执行上面的save命令备份。
为什么会出现all connections are in use错误?
你的lapply循环里反复调用read_html,而read_html底层用curl建立连接,但默认这些连接不会被立即关闭,迭代几万次后直接把系统的连接池耗尽了,新请求自然没法建立。
后续爬取的改进建议(避免再踩坑)
敲黑板!以后爬大量数据时,一定要做这些优化:
- 把
lapply换成for循环,方便中途备份:每爬100/500次就存一次数据,就算中途崩了也只损失最近几次的内容。 - 手动关闭curl连接,避免连接泄漏:用
httr包的GET请求获取页面,爬完后手动关闭连接,示例代码如下:library(rvest) library(httr) # 先补全url的分隔符(你原来的paste可能少了/,导致url格式不对) url_list <- paste("http://www.example.com", 1:130000, sep = "/") GNR <- list() for (idx in seq_along(url_list)) { Sys.sleep(2) # 反爬延迟保留 try({ # 用GET请求获取响应,方便手动管理连接 resp <- GET(url_list[idx]) html_content <- read_html(resp) # 提取数据 title <- html_text(html_nodes(html_content, "h7")) birth_info <- html_text(html_nodes(html_content, "#MainContent_IndividualUC_lblBirth")) GNR[[idx]] <- list(title, birth_info) # 手动关闭连接 close(resp$connection) }) # 每100次备份一次数据 if (idx %% 100 == 0) { backup_file <- paste0("爬取数据_备份_", idx, ".RData") save(GNR, file = backup_file) cat("已备份到", backup_file, "\n") } } # 全部爬完后再做一次最终备份 save(GNR, file = "爬取数据_最终版.RData") - 限制curl的最大连接数:可以用
curl::new_handle()设置maxconnects参数,避免连接池被耗尽:handle <- curl::new_handle(maxconnects = 10) resp <- GET(url_list[idx], handle = handle)
内容的提问来源于stack exchange,提问作者NBK
相关产品推荐
相关产品推荐

