使用R爬取Elsevier多页面嵌套链接时遇NA错误求助
解决Elsevier网站R语言批量爬取时的NA链接错误问题
问题背景
尝试用R语言爬取Elsevier搜索结果(1-1000页),提取文献标题、作者等基础信息,并通过嵌套链接获取摘要,运行时触发错误,无法完成爬取。
错误信息
Scraping: NA Error in `mutate()`: ! Problem while computing `abstract = map_chr(link, get_abstract)`. Caused by error: ! 'NA' does not exist in current working directory ('/home/R'). Run `rlang::last_error()` to see where the error occurred.
错误根源分析
- 链接提取失败:选择器
.external-link无法匹配所有结果的链接,导致部分link字段为NA; - 链接拼接错误:
str_c("https://elsevier.com/https://www.elsevier.com", .)重复拼接域名,生成的链接无效,甚至破坏合法链接格式; - 未处理NA链接:
get_abstract函数直接接收NA值,read_html(NA)会被解析为读取本地文件NA,触发路径不存在错误; - 字段提取逻辑错误:
authors与published、ebook与paperback使用完全相同的选择器,导致提取信息重复且错误。
修复步骤与修正代码
核心修复点
- 修正链接提取规则,使用搜索结果标题的a标签获取正确链接;
- 正确拼接域名,避免重复;
- 为
get_abstract添加错误处理,跳过NA链接或捕获爬取错误; - 修正字段提取的选择器,确保每个字段对应正确页面元素;
- 添加爬取延迟,避免触发反爬机制。
修正后的代码
library(rvest) library(tidyverse) # 生成搜索页面链接(建议先测试少量页面,比如1-5页) page_scopus <- paste0( "https://www.elsevier.com/search-results?query=%28%28%28%28%28%28%E2%80%98Food%20Supply%E2%80%99%29%20OR%20%E2%80%98Food%20Storage%E2%80%99%29%20OR%20%E2%80%98Hunger%E2%80%99%20OR%20food%20security%20OR%20food%20insecurity%20OR%20household%20food%20security%20OR%20global%20food%20security%29%20OR%20household%20food%20insecurity%29%29%29&page=", 1:5 ) # 单页爬取函数 scrap_scopus <- function(page_url) { # 读取页面,添加延迟避免反爬 Sys.sleep(1) page <- read_html(page_url) # 提取搜索结果节点(选择正确的结果容器) results <- page %>% html_elements(".search-result-item") # 提取基础信息 scopus_df <- results %>% map_dfr(~{ title <- .x %>% html_element(".search-result-title a") %>% html_text2() # 修正作者选择器,根据实际页面调整 authors <- .x %>% html_element(".search-result-authors") %>% html_text2() # 修正出版时间选择器,根据实际页面调整 published <- .x %>% html_element(".search-result-meta-item:nth-child(1)") %>% html_text2() # 提取原始链接 raw_link <- .x %>% html_element(".search-result-title a") %>% html_attr("href") # 正确拼接域名(如果raw_link是相对路径) link <- ifelse(is.na(raw_link), NA, paste0("https://www.elsevier.com", raw_link)) tibble(title, authors, published, link) }) # 定义带错误处理的摘要爬取函数 safe_get_abstract <- possibly(function(link) { if (is.na(link)) return(NA_character_) Sys.sleep(0.5) read_html(link) %>% html_element("#description div") %>% html_text2() }, otherwise = NA_character_) # 添加摘要字段 scopus_df %>% mutate(abstract = map_chr(link, safe_get_abstract)) } # 批量爬取(如需更稳定,可改用map_dfr(possibly(scrap_scopus, otherwise = tibble()))) result_scopus <- map_dfr(page_scopus, scrap_scopus) View(result_scopus)
额外注意事项
- 反爬机制:Elsevier有严格的反爬规则,一次性爬取1000页极易被封IP,建议分批次爬取,增加延迟时间(比如
Sys.sleep(2)); - 选择器验证:页面结构可能随时变化,需用浏览器开发者工具(F12)确认元素选择器的正确性;
- 数据合法性:爬取Elsevier内容需遵守网站使用条款,避免用于商业用途或侵犯版权。
内容的提问来源于stack exchange,提问作者Helena
相关产品推荐
相关产品推荐

