R语言爬虫嵌套循环存储变量到dataframe/list问题咨询
现有代码核心问题
- 未读取已下载的本地源码文件:原代码中
webpages对象从未定义,下载完文件后没有调用read_html()加载本地文件内容,后续节点提取根本没有数据源。 - 列表追加逻辑错误:外层按页数循环,内层按每页的条目循环,但你用
datalist[[r]]赋值会覆盖前一页相同位置的条目,自然只会保留最后一页的结果;同时嵌套循环完全冗余,R中可以直接用向量化操作处理整页的提取逻辑,不需要逐行循环。 - 字段提取逻辑不匹配:提取日期、分类、标题时是对整个
headlines向量操作,筛选url时也没有和当前条目对应,会出现字段长度不一致、数据错位的问题。 - 正则存在语法错误:比如日期正则里
[0- 9]多了空格,会匹配失败。
修正后可运行代码
# 加载依赖(tidyverse已内置dplyr、stringr、purrr等包,无需重复加载) library(tidyverse) library(rvest) library(stringi) # 创建存储目录避免报错 dir.create("tempdir", showWarnings = FALSE) datalist <- list() # 逐页爬取 for (page in 1:91) { # 构造链接、下载源码 WebUrl <- paste0("https://www.apple.com/newsroom/archive/?page=", page) dest_file <- paste0("tempdir/Source_code_", page, ".txt") download.file(WebUrl, destfile = dest_file, quiet = TRUE) # 读取本地下载的源码文件 webpages <- read_html(dest_file) # 提取所有a标签属性,提前过滤非新闻链接减少无效计算 webpages_df <- webpages %>% html_nodes("a") %>% map(html_attrs) %>% map_df(~as.list(.)) %>% filter(!is.na(`aria-label`), str_detect(href, "^/newsroom/20")) # 直接用向量化操作提取所有字段,无需嵌套循环 # 苹果新闻室aria-label固定格式为「标题 - 分类 - 日期」,拆分准确率远高于自定义正则 page_df <- webpages_df %>% mutate( Strings = `aria-label`, dates = stri_extract_first(Strings, regex = "[A-Z][a-z]+\\s[0-9]{1,2},\\s[0-9]{4}"), category = str_remove(Strings, paste0(".* -\\s| -\\s", dates)), titles = str_remove(Strings, paste0(" -\\s", category, " -\\s", dates)), article.url = paste0("https://www.apple.com", href) ) %>% select(dates, category, titles, article.url) %>% filter(!is.na(dates)) # 按页数为索引存到列表,不会覆盖之前的结果 datalist[[page]] <- page_df # 可选:打印进度方便排查问题 message("已完成第", page, "页爬取") } # 合并所有页的结果为总结构化数据表 final_df <- bind_rows(datalist)
额外优化建议
- 如果遇到网络波动导致下载失败,可以在
download.file外层加tryCatch跳过错误页,避免整个循环中断。 - 不需要保留本地源码的话,可以不用下载到本地,直接用
read_html(WebUrl)读取网页内容,节省存储空间。
内容的提问来源于stack exchange,提问作者Begre
相关产品推荐
相关产品推荐

