使用RSelenium爬取雅虎财经企业新闻标题及滚动加载的实现问题
RSelenium 爬取雅虎财经企业新闻问题解决方案
一、修复新闻标题提取返回空的问题
原代码返回空值有两个核心原因:
- 定位方式兼容性不足:RSelenium 中
using = "class"仅能匹配class属性完全等于指定值的元素,而雅虎财经的StretchedBox元素通常附带多个类名,因此匹配失败。 - 静态等待不可靠:固定5秒等待无法适配不同网络环境下的页面加载速度,元素未渲染完成就执行查找自然返回空。
修复后的代码示例:
library('RSelenium') # 启动远程浏览器 rD <- rsDriver(port = 4840L, browser = c("firefox")) remDr <- rD[["client"]] # 跳转至指定企业的雅虎财经新闻页 remDr$navigate("https://finance.yahoo.com/quote/AAPL/news?p=AAPL") # 处理cookie同意按钮 webElems <- remDr$findElements(using = "xpath", "//button[starts-with(@class, 'btn primary')]") webElems[[1]]$clickElement() # 显式等待最多15秒,直到StretchedBox元素加载完成 max_wait <- 15 start_time <- Sys.time() boxes <- list() while(length(boxes) == 0 & difftime(Sys.time(), start_time, units = "secs") < max_wait){ # 改用css selector匹配包含StretchedBox类的所有元素 boxes <- remDr$findElements(using = "css selector", ".StretchedBox") Sys.sleep(1) } # 提取新闻标题并存储 news_titles <- c() if(length(boxes) > 0){ for(box in boxes){ # 定位StretchedBox对应新闻卡片中的h3标题元素 title_elem <- box$findElement(using = "xpath", "./ancestor::li//h3") news_titles <- c(news_titles, title_elem$getElementText()[[1]]) } # 输出查看结果 print(news_titles) # 存储至本地csv write.csv(data.frame(新闻标题 = news_titles), "AAPL新闻.csv", row.names = FALSE) }
二、滚动加载更多历史新闻
雅虎财经新闻采用滚动加载机制,只有页面滚动到底部才会触发下一批内容加载,可通过执行JS实现滚动,配合循环获取多页内容:
# 滚动参数配置 scroll_count <- 10 # 滚动次数,可根据需要的新闻量调整 pause_per_scroll <- 3 # 每次滚动后等待加载的秒数 all_titles <- c() for(i in 1:scroll_count){ # 执行JS滚动到页面底部 remDr$executeScript("window.scrollTo(0, document.body.scrollHeight);") Sys.sleep(pause_per_scroll) # 提取当前页所有标题并去重 current_boxes <- remDr$findElements(using = "css selector", ".StretchedBox") current_titles <- unlist(lapply(current_boxes, function(x){ title_elem <- x$findElement(using = "xpath", "./ancestor::li//h3") title_elem$getElementText()[[1]] })) all_titles <- unique(c(all_titles, current_titles)) # 可选逻辑:按时间范围停止滚动 # 定位新闻发布时间元素<time>,转换为日期格式后和目标起始日期对比,早于目标日期则break跳出循环 } # 存储全部爬取的新闻 write.csv(data.frame(新闻标题 = all_titles), "AAPL全量新闻.csv", row.names = FALSE) # 任务完成后关闭驱动和浏览器 remDr$close() rD$server$stop()
注意事项
- 滚动间隔不要设置过短,避免页面未加载完成就执行下一次操作,导致内容重复或者漏抓
- 如果需要精准控制爬取的时间范围,可解析新闻卡片中的
<time>标签的datetime属性,转换为日期格式后做逻辑判断即可
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

