使用Rvest循环从多URL抓取文本至数据框遇问题求助
问题分析与解决方案
你的循环爬取失败主要有几个核心问题,先逐个拆解,再给你可运行的代码:
1. 原代码的问题点
针对lapply版本:
urls是read_csv读取的数据框,直接用lapply(urls, ...)会遍历数据框的列,而非每行的URL,需先提取URL所在列(假设列名叫url)转成字符向量再遍历。html_nodes(pg, "div.ListingStatusBannerSection")与html_text()之间缺少管道符%>%,导致html_text()未作用在目标节点上,调用无参的html_text()必然出错。- 未处理页面加载失败的情况,单个URL报错会直接中断整个循环。
针对for循环版本:
for(i in length(urls))只会循环1次(length(urls)返回的是数据框列数),正确写法应为for(i in 1:nrow(urls))。- 管道符写错成
%>,标准写法是%>%。 - 提取URL的方式错误:
link = paste0(urls[i])无法正确获取单行URL,应使用urls$url[i](假设列名为url)。 - 页面对象调用错误:
page <- read_html(link[i])中link已是单个URL,无需加[i];后续html_nodes(page[i], ...)也错误,page本身就是单个页面,不需要索引。 - 未保存爬取结果:循环中没有把每次的抓取内容存入变量,最后
df <- data.frame(urls,webpage)里的webpage未定义。
2. 正确实现代码
方法一:用lapply(推荐,更简洁)
library(tidyverse) library(rvest) # 读取URL文件,假设URL所在列名为url urls_df <- read_csv('C:\\Users\\XXXXX\\URLFile.csv', show_col_types = FALSE) urls <- urls_df$url # 提取URL为字符向量 # 定义爬取函数,加入错误处理与反爬设置 scrape_redfin <- function(url) { Sys.sleep(2) # 加2秒延迟,避免触发反爬 tryCatch({ # 模拟浏览器请求头,降低被拦截概率 pg <- read_html(url, user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36") # 定位目标节点并提取清洗后的文本 status_text <- pg %>% html_nodes("div.ListingStatusBannerSection") %>% html_text2() # html_text2自动处理换行、空格,比html_text更干净 status_text }, error = function(e) { # 出错时返回NA,同时打印错误信息,不中断循环 message(paste("爬取失败:", url, "错误信息:", e$message)) return(NA) }) } # 批量爬取 results <- lapply(urls, scrape_redfin) # 整理成数据框 final_df <- tibble(url = urls, last_sold_info = unlist(results))
方法二:用for循环
library(tidyverse) library(rvest) urls_df <- read_csv('C:\\Users\\XXXXX\\URLFile.csv', show_col_types = FALSE) urls <- urls_df$url results <- vector("character", length(urls)) # 初始化结果存储向量 for(i in 1:length(urls)) { Sys.sleep(2) current_url <- urls[i] tryCatch({ pg <- read_html(current_url, user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36") results[i] <- pg %>% html_nodes("div.ListingStatusBannerSection") %>% html_text2() }, error = function(e) { message(paste("第", i, "个URL爬取失败:", current_url, "错误信息:", e$message)) results[i] <- NA }) } final_df <- tibble(url = urls, last_sold_info = results)
3. 关键注意事项
- 反爬处理:Redfin有反爬机制,必须加
Sys.sleep()设置延迟,同时配置user_agent模拟浏览器请求,否则极易被封IP。 - 节点验证:如果
div.ListingStatusBannerSection抓不到数据,打开目标页面按F12检查元素,确认节点选择器是否因网站更新DOM结构而失效。 - 数据清洗:若需要更精细的文本处理,可在
html_text2()后追加str_squish()进一步去除多余空格。
内容的提问来源于stack exchange,提问作者youconmeconwecon
相关产品推荐
相关产品推荐

