使用ralger包scrap爬取Indeed职位描述返回缺失值及行数不匹配报错
报错原因
- 你使用的
ralger::scrap()函数在批量爬取时,会自动跳过请求失败、页面DOM节点匹配失败的条目,不会为失败条目返回占位值,因此最终得到的job_description向量长度小于传入的链接总数,拼接数据框时就会触发行数不一致的报错。 - Indeed站点配置了反爬规则,短时间高频发起请求会随机拦截部分访问,因此每次运行代码时,成功爬取的条目数会出现波动,无法稳定得到和链接数等量的结果。
修复方案
核心思路是放弃批量传入链接的爬取方式,改为逐链接爬取+失败自动填充NA,同时加入随机延时、重试逻辑降低反爬触发概率,保证最终职位描述向量和链接向量长度完全一致。
修正后的可运行代码如下:
library(ralger) library(purrr) # 搜索页配置 base_link <- "https://www.indeed.com/jobs?q&l=mexico&from=searchOnHP&vjk=c339451b33a29c91" links <- paste0(base_link, 1:100) # 提取职位详情页链接 scraped_url <- attribute_scrap(links, node = '[data-hide-spinner = "true"]', attr = 'href') job_url <- paste0("https://www.indeed.com", scraped_url) # 单条职位描述爬取函数,失败返回NA,支持重试 scrap_single_jd <- function(target_url, max_retry = 2) { jd_content <- NA_character_ for (attempt in 1:max_retry) { tryCatch({ tmp_res <- scrap(link = target_url, node = '.jobsearch-jobDescriptionText') # 校验返回结果有效性,空结果判定为爬取失败 if (length(tmp_res) >= 1 && sum(nchar(tmp_res)) > 0) { jd_content <- paste0(tmp_res, collapse = " ") break } }, error = function(e) { # 捕获错误不中断流程 }) # 随机延时1-3秒,降低被反爬拦截的概率 Sys.sleep(runif(1, min = 1, max = 3)) } return(jd_content) } # 逐页爬取所有职位描述 job_description <- map_chr(job_url, scrap_single_jd) # 构建数据集,此时两向量长度完全匹配,不会触发行数报错 df <- data.frame(job_description, job_url)
代码运行后,所有爬取失败的职位描述都会被统一替换为
NA,不会再出现拼接数据框的报错。如果需要进一步提升爬取成功率,可以适当调长请求延时区间,或搭配代理IP池绕过站点反爬限制。
内容的提问来源于stack exchange,提问作者Mura
相关产品推荐
相关产品推荐

