R爬取Goodreads评论出现行数量不一致错误求助
这个错误的核心原因很明确:你在构建数据框时,reviewId向量的行数和其他字段(比如评论内容、评分等)的行数不一致。比如有的页面里你提取到31个reviewId,但其他数据只有30条,或者反过来,R就会报错说参数暗示不同的行数。
为什么你的两种提取方式都会出问题?
第一种方式
str_extract("/review/show/\\d+"):
你是直接在整个页面的HTML里全局匹配这个模式,但Goodreads的页面里可能存在额外的匹配项(比如页面侧边的推荐评论链接、底部的相关链接),或者部分评论没有这个格式的链接,导致提取到的reviewId数量和实际评论数不匹配——只有部分书籍触发是因为这些书籍的页面刚好存在这种不一致的情况。第二种方式
str_extract("review_\\d+"):
这个匹配模式不符合Goodreads页面里reviewId的实际格式,所以完全匹配不到任何结果,reviewId变成了长度为0的向量,和其他有30行的数据拼接时自然会报错。
具体解决步骤
要解决这个问题,核心思路是先定位到每条评论的独立容器节点,再从每个容器内提取对应的字段,这样能保证每个评论的所有字段行数完全一致。
步骤1:定位评论容器节点
Goodreads的每条评论通常包裹在一个带有特定类名的<div>节点里(比如div.review,具体可以通过浏览器开发者工具查看页面结构确认)。用rvest的html_nodes先抓取所有评论容器:
# 假设你已经用rvest获取了页面的HTML对象(比如reviews.html <- read_html(url)) review_containers <- reviews.html %>% html_nodes("div.review")
步骤2:从容器内提取reviewId
Goodreads通常会把reviewId放在评论容器的data-review-id属性里,这是最可靠的提取方式;如果没有这个属性,再在容器内找评论链接提取:
# 优先从data属性提取(最准确) reviewId <- review_containers %>% html_attr("data-review-id") # 如果data属性不存在,再从容器内的链接提取: # reviewId <- review_containers %>% # html_node("a[href*='/review/show/']") %>% # 找容器内包含/review/show/的链接 # html_attr("href") %>% # stringr::str_extract("\\d+") # 提取数字部分
步骤3:处理缺失值(可选)
如果个别评论容器里没有提取到reviewId,用tidyr::replace_na填充缺失值,保证向量长度和其他字段一致:
library(tidyr) reviewId <- reviewId %>% replace_na("unknown_review_id") # 或者保留NA,根据你的匿名化需求调整
步骤4:提取其他字段并构建数据框
接下来提取评论内容、评分等其他字段时,也从review_containers里提取,这样所有字段的行数都会和评论数量一致:
# 示例:提取评论文本 review_text <- review_containers %>% html_node(".reviewText") %>% html_text(trim = TRUE) # 构建数据框,此时不会再出现行数不匹配的问题 reviews_df <- data.frame( reviewId = reviewId, text = review_text, check.names = FALSE )
步骤5:验证测试
用之前报错的书籍页面(比如《使女的故事》)测试,通过以下代码确认各向量长度一致:
cat("评论容器数量:", length(review_containers), "\n") cat("reviewId数量:", length(reviewId), "\n") cat("评论文本数量:", length(review_text), "\n")
如果三个数字相同,说明提取逻辑没问题,数据框可以正常构建。
内容的提问来源于stack exchange,提问作者MartinH

