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

在嵌套For循环中嵌入if语句的论坛爬虫问题排查

问题分析与修正方案

核心错误点

  1. URL读取错误:page = read_html(page) 变量名重复,需用拼接好的link作为参数,否则第一次循环时page未定义会直接报错。
  2. 下一页判断逻辑缺陷:未找到下一页按钮时,html_attr('rel')返回空向量,直接用== "next"做条件会触发错误(if要求逻辑值长度为1),需先判断节点是否存在。
  3. 正则表达式无效:str_remove('p*') 中的p*是正则语法,仅匹配0个或多个字母p,无法正确处理分页路径,若原URL不含分页,这一步完全多余。
  4. 数据拼接效率低下:循环中用rbind反复拼接数据框会大幅拖慢性能,改用列表收集数据后一次性绑定更高效。

修正后的代码

library(tidyverse)
library(rvest)
library(lubridate)

df_comments_list <- list()  # 用列表存储每页数据,提升性能

for (j in df_iva$url) {
  for (i in seq(from = 1, to = 100000, by = 1)){
    link <- paste0(j, "/p", i)
    page <- read_html(link)  # 修正:使用拼接好的分页URL
    Sys.sleep(runif(1, min=1.29, max=4.89))
    
    # 修正标题提取:仅去除固定前缀即可
    post_title <- str_remove(j, 'https://forums.moneysavingexpert.com/discussion/')
    user <- page %>% html_nodes(xpath = '//a[@class="Username js-userCard"]') %>% html_attr('data-userid')
    date_time <- page %>% html_nodes(xpath = '//div[@class="DataBox DataBox-Comments"]//div[@class="Meta RecordMeta"]//span[@class="MItem DateCreated"]//a//time') %>% html_attr('datetime') %>% ymd_hms()
    
    # 将当前页数据存入列表
    df_comments_list[[length(df_comments_list) + 1]] <- tibble(post_title, user, date_time)
    
    # 修正下一页判断:先检查节点存在性,再验证rel属性
    next_btn <- page %>% html_nodes(xpath = '//div[@class="P PagerWrap"]//a[@class="Next"]')
    if (length(next_btn) > 0 && html_attr(next_btn, 'rel') == "next") {
      print(link)
    } else {
      print("finished")
      break
    }
  }
  print(paste0("#####     ", j, "     ####"))
  Sys.sleep(runif(1, min=3.29, max=12.89))
}

# 一次性绑定所有页面的数据
df_comments <- bind_rows(df_comments_list)

额外优化建议

  • 增加错误捕获:用tryCatch包裹read_html,避免单个页面请求失败导致整个爬虫中断。
  • 日志记录:除打印链接外,可将爬取状态写入本地日志文件,方便后续排查问题。
  • 分页适配:若论坛主URL本身就是第一页(无需/p1),可调整循环起始为2,先单独爬取j作为第一页数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:28:33