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

使用rvest进行网页爬取循环时遇到的三类问题

解决期刊引文爬取的三个常见问题

我来帮你逐个搞定这三个爬取和数据整理的问题,直接上修改后的代码和详细解释:

问题1:生成长向量而非表格

你的scrape函数返回的是cbind生成的矩阵,再加上lapply会把每个网页的结果存成列表元素,自然没法直接形成规整的表格。我们需要让每个scrape调用返回单行数据框,之后再把所有行合并成完整的DataFrame。

问题2:read_xml报错factor类型

read.csv默认会把字符型列(比如你的URL链接)转换成factor类型,而read_html需要的是纯字符型输入。解决方法很简单:读取CSV时加上stringsAsFactors = FALSE,或者用readr::read_csv(更推荐,默认不转factor)。

问题3:多个邮箱生成多行数据

当一篇文章有多个邮箱时,我们需要让同一篇文章的其他信息重复对应每个邮箱,生成多行数据。这里用tidyr::unnest就能轻松实现,不用手动写复杂的循环。


修改后的完整代码

先加载需要的工具包:

library(rvest)
library(dplyr)
library(tidyr) # 专门处理多行拆分的工具
library(purrr) # 更便捷的列表处理

改进后的爬取函数

scrape <- function(x){
  doc <- read_html(x)
  
  # 用html_text2替代html_text,自动清理多余换行和空格,提取的文本更干净
  author <- html_text2(html_nodes(doc, '.art_authors'))
  year <- html_text2(html_nodes(doc, '.year'))
  journalName <- html_text2(html_nodes(doc, '.journalName'))
  art_title <- html_text2(html_nodes(doc, '.art_title'))
  volume <- html_text2(html_nodes(doc, '.volume'))
  page <- html_text2(html_nodes(doc, '.page'))
  email <- html_text2(html_nodes(doc, xpath = "//a[@class = 'email']"))
  
  # 处理空值:如果字段为空,设为NA;邮箱为空时设为长度1的NA,方便后续合并
  author <- if(length(author) == 0) NA_character_ else author
  year <- if(length(year) == 0) NA_character_ else year
  journalName <- if(length(journalName) == 0) NA_character_ else journalName
  art_title <- if(length(art_title) == 0) NA_character_ else art_title
  volume <- if(length(volume) == 0) NA_character_ else volume
  page <- if(length(page) == 0) NA_character_ else page
  email <- if(length(email) == 0) NA_character_ else email
  
  # 返回数据框:用tibble替代基础data.frame,更适配tidyverse工具链
  tibble(
    Author = author,
    Year = year,
    Journal_Name = journalName,
    Art_Title = art_title,
    Volume = volume,
    Page = page,
    Email = email
  ) %>% 
    unnest_longer(Email) # 自动把多个邮箱拆分成单独行,其他字段同步重复
}

用URL向量直接测试

data <- c("http://journals.sagepub.com/doi/abs/10.3102/0013189X037001060", 
          "http://journals.sagepub.com/doi/abs/10.3102/0013189X037002102", 
          "http://journals.sagepub.com/doi/abs/10.3102/0013189X037002104", 
          "http://journals.sagepub.com/doi/full/10.3102/0013189X17737739")

# 用map_dfr自动合并所有爬取结果成一个数据框,比lapply+do.call更简洁
y <- map_dfr(data, scrape)
View(y)

从CSV加载URL的正确方式

# 方法1:基础包read.csv,指定不转factor
data <- read.csv("link_test.csv", stringsAsFactors = FALSE)
y <- map_dfr(data$link, scrape)

# 方法2:推荐用readr包,默认不转factor,读取速度也更快
# data <- read_csv("link_test.csv")
# y <- map_dfr(data$link, scrape)

关键改动说明

  1. 返回标准数据框:用tibble替代cbind生成的矩阵,确保每个爬取结果是规整的数据结构,方便后续合并。
  2. 解决factor类型报错:读取CSV时禁用自动转factor,保证URL是纯字符型,让read_html可以正常处理。
  3. 自动拆分多邮箱:unnest_longer(Email)会自动把每个邮箱拆成单独一行,同时重复其他字段的内容,完美匹配你的需求。
  4. 更稳定的文本提取:html_text2会自动清理网页文本中的多余换行、空格,提取的内容更整洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:11:27