R语言网页抓取报错:提取2017-2018年世界大学排名遇问题
排查与解决rvest爬取泰晤士高等教育排名的报错问题
我来帮你梳理下用R的rvest包爬取2017/2018年泰晤士高等教育世界大学排名时可能遇到的报错原因,以及对应的解决办法:
1. 动态页面渲染导致内容无法抓取
泰晤士高等教育的排名页面大量内容是通过JavaScript动态加载的,而rvest只能抓取静态HTML源码——这是最常见的报错根源:你用read_html()拿到的内容里根本没有排名数据,后续解析自然会报错。
解决办法:用RSelenium模拟浏览器加载动态内容
RSelenium可以模拟真实浏览器的行为,完整加载所有动态渲染的内容,再进行数据提取。示例代码如下:
library(RSelenium) library(rvest) # 启动Chrome浏览器(需提前安装ChromeDriver并配置好环境) driver <- rsDriver(browser = "chrome", port = 4567L) remDr <- driver[["client"]] # 访问目标页面 url <- "https://www.timeshighereducation.com/world-university-rankings/2018/world-ranking#!/page/0/length/-1/sort_by/scores_international_outlook/sort_order/asc/cols/scores" remDr$navigate(url) # 等待页面完全加载(可根据网络情况调整等待时间) Sys.sleep(5) # 获取完整页面源码并解析 page_source <- remDr$getPageSource()[[1]] webpage <- read_html(page_source) # 提取排名数据(示例:大学名称与排名,需根据实际HTML结构调整选择器) university_names <- webpage %>% html_nodes(".uni-link") %>% html_text(trim = TRUE) rankings <- webpage %>% html_nodes(".rank") %>% html_text(trim = TRUE) # 关闭浏览器服务 remDr$close() driver$server$stop() # 整理成数据框 rank_df <- data.frame(Rank = rankings, University = university_names) head(rank_df)
2. 反爬机制拦截请求
直接用rvest发起请求可能会被网站识别为机器人,返回403错误或空内容。
解决办法:添加请求头伪装成浏览器
用httr包设置User-Agent等请求头,绕过基础反爬机制:
library(rvest) library(httr) url <- "https://www.timeshighereducation.com/world-university-rankings/2018/world-ranking#!/page/0/length/-1/sort_by/scores_international_outlook/sort_order/asc/cols/scores" # 模拟Chrome浏览器的请求头 headers <- add_headers( "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" ) # 发送请求并解析页面 response <- GET(url, headers) webpage <- read_html(response) # 后续数据提取步骤...
注:这种方法仅能绕过基础反爬,若页面仍有动态加载内容,还是需要结合RSelenium使用。
3. CSS/XPath选择器错误
如果后续用html_nodes()时选择器写错,会返回空结果或直接报错。
解决办法:检查页面HTML结构
打开目标页面,右键选择“检查”元素,找到排名数据对应的HTML标签,复制正确的CSS选择器或XPath。比如大学名称可能在a.uni-link标签里,排名可能在td.rank里,需根据当前页面的实际结构调整。
4. URL参数限制问题
你URL中的length/-1是想一次性获取全量排名,但网站可能限制了单次请求的返回数量,或参数格式不正确,导致内容加载异常。
解决办法:分页面抓取
如果全量抓取失败,可以尝试分页面爬取:循环修改URL中的page/0为page/1、page/2等,逐个页面获取数据后再合并。
内容的提问来源于stack exchange,提问作者Neeraj Choudhary
相关产品推荐
相关产品推荐

