R语言scholar包循环调用get_scholar_id下标越界、单独调用正常问题
报错根因定位
- 这个问题和for循环的写法完全无关,不管是按固定索引范围遍历,还是用
seq_along取索引的写法,本身语法逻辑没有任何问题。 - 触发报错的核心原因是
scholar包的get_scholar_id函数本身没有做全场景的异常容错:- 当Google Scholar接口返回的结果页没有匹配条目、或是接口返回结构不符合函数预期时,函数内部会直接访问结果列表的第1个元素
tables[[1]] - 此时列表是空的,不存在第1个元素,就会抛出下标越界的错误,直接中断整个循环流程
- 当Google Scholar接口返回的结果页没有匹配条目、或是接口返回结构不符合函数预期时,函数内部会直接访问结果列表的第1个元素
你观察到的“固定传入第3位学者的参数就能正常返回ID”的现象,本质是循环在遍历过程中,刚跑到前两位学者(Colditz、Lander)的匹配空结果场景时,就因为无容错的报错直接中断了,根本没机会执行到第3位学者的正常请求步骤,不是循环本身的逻辑问题。
可稳定批量运行的实现方案
核心思路是给每一次函数调用加上异常捕获,避免单个条目的报错中断整个批量流程,同时降低反爬拦截概率:
- 用
tryCatch包裹每次get_scholar_id调用,碰到报错、空结果、警告时直接返回缺失值,不中断循环 - 每次请求后加随机延迟,减少短时间高频请求被Google Scholar拦截的概率
- 预先分配结果存储的向量空间,避免循环中反复覆盖之前的结果
可直接复用的代码示例:
# 预先初始化和学者名录长度一致的结果向量 scholar_id_vec <- rep(NA_character_, nrow(df)) for(i in seq_along(df$Last.Name)){ # 包裹异常捕获,任何调用错误都不中断循环 res <- tryCatch( get_scholar_id( last_name = df$Last.Name[i], first_name = df$First.Name[i] ), # 接住运行时错误,返回缺失值 error = function(e) NA_character_, # 接住空结果的警告,返回缺失值 warning = function(w) NA_character_ ) # 将结果存入对应位置 scholar_id_vec[i] <- res # 随机延迟2-4秒,规避反爬限制 Sys.sleep(runif(1, 2, 4)) } # 将批量获取的ID合并回原始学者名录 df$google_scholar_id <- scholar_id_vec
补充注意事项
- 之前循环运行时反复出现的"No Scholar ID found"提示,本身属于警告级别的提示,本来不会中断流程;但当碰到接口返回结构完全异常的场景时,这类提示就会升级为无容错的运行时错误,靠
tryCatch可以把所有异常场景统一接住。 - 如果最终获取到的空值比例较高,可以在调用
get_scholar_id时补充传入affiliation(所属机构)参数,缩小搜索范围,减少重名导致的匹配为空的情况。
内容的提问来源于stack exchange,提问作者perrier
相关产品推荐
相关产品推荐

