You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用parLapply并行调用rvest爬取O*NET遇连接错误求助

解决方案

1. 降低并行规模+添加请求延迟

31核同时发起请求远超O*NET公共服务的承受能力,直接触发服务器拒绝连接或反爬限制。建议将并行核数降至8-12(预留2核给系统),同时给每个请求添加随机延迟,模拟人工访问节奏:

library(parallel)
library(rvest)
library(httr)

# 带延迟、重试的爬取函数
scrape_soc <- function(title) {
  # 1-3秒随机延迟
  Sys.sleep(runif(1, 1, 3))
  
  result <- tryCatch({
    url <- paste0("https://www.onetonline.org/find/quick?s=", URLencode(title))
    # 模拟浏览器UA,避免被识别为爬虫
    resp <- GET(url, user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"))
    
    # 非200状态码时重试1次
    if (status_code(resp) != 200) {
      Sys.sleep(5)
      resp <- GET(url, user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"))
      if (status_code(resp) != 200) return(NA)
    }
    
    page <- read_html(resp)
    soc_code <- page %>% html_element("td:nth-child(1)") %>% html_text()
    soc_code
  }, error = function(e) {
    message(sprintf("Failed to process '%s': %s", title, e$message))
    NA
  })
  
  result
}

# 初始化并行集群(用8核)
num_cores <- min(detectCores() - 2, 8)
cl <- makeCluster(num_cores)
clusterExport(cl, c("scrape_soc", "URLencode", "GET", "status_code", "read_html", "html_element", "html_text", "runif", "Sys.sleep"))
clusterEvalQ(cl, {
  library(rvest)
  library(httr)
})

# 分批处理150万条数据(每批1万条)
batch_size <- 10000
total_batches <- ceiling(length(job_titles) / batch_size)
all_results <- character(length(job_titles))

for (batch in 1:total_batches) {
  start <- (batch - 1) * batch_size + 1
  end <- min(batch * batch_size, length(job_titles))
  batch_titles <- job_titles[start:end]
  
  batch_res <- parLapply(cl, batch_titles, scrape_soc)
  all_results[start:end] <- unlist(batch_res)
  
  # 每批完成后保存进度,避免丢失
  saveRDS(all_results, sprintf("soc_progress_batch_%d.rds", batch))
  # 批次间额外延迟10秒,减轻服务器压力
  Sys.sleep(10)
}

stopCluster(cl)

2. 修正tryCatch的作用范围

之前的tryCatch可能只包裹了部分逻辑,导致连接错误未被捕获。必须将GET请求、页面解析等所有可能出错的步骤全部纳入tryCatch范围,确保任何异常都能被捕获并返回NA,避免并行进程崩溃。

3. 会话保持优化

使用httr::handle建立持久会话,减少重复TCP连接的开销,提升请求稳定性:

# 在集群初始化前创建会话句柄
session_handle <- handle("https://www.onetonline.org")

# 修改scrape_soc中的请求部分
resp <- GET(url, user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"), handle = session_handle)

4. 优先使用官方批量服务

O*NET提供官方开发者API和批量数据下载服务,相比网页爬取,官方渠道更稳定、合规,完全适配大规模数据查询需求,这是解决问题的最优方案。


内容的提问来源于stack exchange,提问作者abgeorge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 07:35:33