基于rvest+RSelenium抓取多视图动态德甲点球射手榜问题
问题分析与解决方案
看起来你遇到的核心问题是没有正确获取动态加载后的页面源码,而且忽略了页面加载的等待时间,导致后续页面的抓取结果为空。咱们一步步来修正:
错误点拆解
- 点击下一页后,你仍然使用初始的
read_html(elfer_url)获取页面,这是静态的HTML,根本不会包含动态加载出来的新视图内容——动态渲染的内容只存在于RSelenium控制的浏览器会话里。 - 没有等待页面加载完成就立即抓取,浏览器还没渲染出新的
#elferspielerhistorie_subcont_j节点,自然抓不到内容。 - 使用了
html_node()而非html_nodes(),前者只返回第一个匹配元素,后者才会返回所有目标td节点,这也会导致数据缺失。 - 循环范围有误:34个视图对应j从0到33,所以循环应该从j=1到j=33,而不是j<=34。
修正后的完整代码
library(rvest) library(tidyverse) library(RSelenium) # 初始化浏览器会话 elfer_url <- "http://www.kicker.de/news/fussball/bundesliga/spieltag/1-bundesliga/elfmeter-schuetzen-geschichte.html" rD <- rsDriver(port = 4444L, browser = "firefox") remDr <- rD$client remDr$navigate(elfer_url) # 等待页面初始加载(给浏览器一点时间) Sys.sleep(2) # 抓取第一页(j=0) page_source <- remDr$getPageSource()[[1]] # 获取当前浏览器的页面源码 elfmeter <- read_html(page_source) Schuetzen <- elfmeter %>% html_nodes("#elferspielerhistorie_subcont_0 td") %>% html_text() %>% matrix(ncol=10, byrow=T) %>% data.frame(stringsAsFactors = FALSE) # 定位"下一页"按钮 clicknext <- remDr$findElement("xpath","//*[@id='ctl00_PlaceHolderContent_elfer_blaettern_elferhistorie_PagerForward']") # 循环抓取剩下的33个视图(j=1到j=33) for(j in 1:33){ # 点击下一页 clicknext$clickElement() # 等待页面加载(关键!根据网络情况调整时间) Sys.sleep(2) # 获取当前页面的源码 page_source <- remDr$getPageSource()[[1]] elfmeter <- read_html(page_source) # 抓取当前视图的td节点 current_node <- paste0("#elferspielerhistorie_subcont_",j," td") weitere_Schuetzen <- elfmeter %>% html_nodes(current_node) %>% html_text() %>% matrix(ncol=10, byrow=T) %>% data.frame(stringsAsFactors = FALSE) # 合并数据 Schuetzen <- rbind(Schuetzen, weitere_Schuetzen) print(paste("已完成第", j+1, "页抓取")) } # 关闭浏览器会话 remDr$close() rD$server$stop()
额外优化建议
- 可以用更智能的等待方式替代
Sys.sleep(),比如等待目标节点出现后再抓取,避免固定等待时间的浪费或不足:# 示例:等待当前视图的节点出现 remDr$waitForElement(using = "css", current_node, timeout = 10000) - 给数据框添加列名,让结果更清晰:
colnames(Schuetzen) <- c("排名", "球员", "俱乐部", "总进球", "2023/24", "2022/23", "2021/22", "2020/21", "2019/20", "更早赛季")
内容的提问来源于stack exchange,提问作者Christoph Hanck
相关产品推荐
相关产品推荐

