TripAdvisor评论爬取异常:添加评分等字段仅获第一页数据求助
嘿,我来帮你搞定这个爬虫问题!你遇到的情况很典型——加了几个字段后就只能爬第一页,大概率是选择器跨分页失效或者缺失值没处理导致循环中断了,咱们一步步来排查解决:
问题根源分析
- 选择器适配问题:TripAdvisor的分页页面结构可能和第一页略有差异,你原来用的选择器(比如
.rating span)在第二页及以后可能抓不到目标元素,返回NA后,后续的gsub这类字符串处理函数遇到NA就会报错,直接中断循环。 - 缺失值未处理:部分评论可能没有标题(quote),或者评分节点加载异常,导致字段向量长度不一致,无法正常合并数据框。
- 初始数据结构混乱:你开头初始化的
df包含Date, File, User字段,但循环里又改成了id, review结构,虽然初始是空的,但新增字段后容易出现列不匹配的问题。
修正后的代码(带详细改进)
# 加载依赖包,新增dplyr让数据处理更稳健 library(tm) library(stringr) library(rvest) library(dplyr) # 初始化统一结构的空数据框,包含所有要爬取的字段 df <- tibble( id = character(), quote = character(), rating = integer(), date = POSIXct(), review = character() ) x <- 0 max_pages <- 500 # 可根据实际存在的页数调整,不用硬爬500页 for(i in 1:max_pages){ # 构造分页URL url <- if(x == 0){ "https://www.tripadvisor.co.uk/Attraction_Review-g209948-d189773-Reviews-Giant_s_Causeway-Bushmills_County_Antrim_Northern_Ireland.html" } else { paste0("https://www.tripadvisor.com/Attraction_Review-g209948-d189773-Reviews-or", x, "-Giant_s_Causeway-Bushmills_County_Antrim_Northern_Ireland.html#REVIEWS") } # 加入错误捕获,单页爬取失败也不会中断整个循环 tryCatch({ page <- read_html(url) reviews <- page %>% html_nodes("#REVIEWS .innerBubble") # 逐个抓取字段,同时处理缺失值 id <- reviews %>% html_node(".quote a") %>% html_attr("id") %>% replace_na("") quote <- reviews %>% html_node(".quote span") %>% html_text() %>% replace_na("无评论标题") # 修正评分选择器:直接定位带评分的class,适配所有分页页面 rating <- reviews %>% html_node(".ui_bubble_rating") %>% html_attr("class") %>% str_replace_all("ui_bubble_rating bubble_", "") %>% str_remove("0") %>% as.integer() %>% replace_na(0) # 用0标记缺失的评分 # 修正日期选择器:直接找ratingDate节点,避免父节点限制 date <- reviews %>% html_node(".ratingDate") %>% html_attr("title") %>% strptime("%d %b %Y") %>% as.POSIXct() %>% replace_na(as.POSIXct(NA)) review <- reviews %>% html_node(".entry .partial_entry") %>% html_text() %>% replace_na("") # 创建临时数据框并合并到主表 temp_df <- tibble(id, quote, rating, date, review) df <- bind_rows(df, temp_df) # 更新分页参数,打印爬取进度 x <- x + 10 cat("成功爬取第", i, "页,当前总评论数:", nrow(df), "\n") # 礼貌爬取,避免被封IP Sys.sleep(2) }, error = function(e){ cat("第", i, "页爬取失败:", e$message, "\n") x <- x + 10 next }) }
关键改进说明
- 选择器优化:把评分和日期的选择器改成更通用的定位方式(比如直接用
.ui_bubble_rating),确保所有分页页面都能抓到数据。 - 缺失值处理:用
replace_na给每个字段的缺失值补充默认值,保证向量长度一致,不会因为某条评论缺字段导致循环崩溃。 - 错误捕获:
tryCatch让单页爬取失败时不中断整个循环,还能打印错误信息方便排查问题。 - 统一数据结构:初始
tibble就包含所有目标字段,后续合并不会出现列不匹配的问题。 - 礼貌爬取:添加
Sys.sleep(2)避免请求过于频繁,防止被TripAdvisor封禁IP。
额外提醒
记得先查看TripAdvisor的robots.txt确认爬取规则,不要过度爬取哦!如果还是有问题,可以手动打开第二页,用浏览器开发者工具检查字段的实际HTML结构,再调整选择器即可。
内容的提问来源于stack exchange,提问作者GaB
相关产品推荐
相关产品推荐

