R语言rvest通过CSS选择器抓取nomics数据时节点返回多余数据问题
问题根本原因
CSS选择器抓取加密资产页失效的原因
- 你之前能顺利抓交易所数据,是因为交易所列表页是服务端直出的静态表格,用到的CSS类没有在页面其他模块复用,选出来的节点刚好一一对应表格列,不会有冗余。
- 加密资产页是Next.js框架开发的客户端渲染页面,用的是Tailwind风格的原子化CSS,你复制的那些短class名(比如
.flex-column.n-pl6、.overflow-visible)是全站通用的样式类,导航栏、广告位、推荐模块、底部组件全在复用同名类。你在开发者工具里点选的时候视觉上只选中了表格内容,但rvest拉取到的完整源码里,这些选择器会匹配到上百个非目标节点,抓出来的内容自然混杂冗余、行列错位。手动按行号筛选属于碰运气的做法,只要页面插个公告、调整下模块位置,筛选规则就失效,翻页时不同页的组件结构有细微差异就会直接乱套。
__NEXT_DATA__方案循环执行失败的原因
- 变量名不一致:你初始化的空存储列表叫
datalist,循环内赋值时却写入了listings对象,后续合并时找不到对应数据自然报错。 - 翻页URL拼接错误:加密资产列表的翻页规则不是根域名后直接加数字,第一页是
https://nomics.com/,第二页及以后是https://nomics.com/?page=页码的参数格式,你之前拼出来的https://nomics.com/2是无效路径,拿不到正确的列表数据。 - 合并方法兼容性差:基础
rbind要求所有待合并数据的列顺序、列名完全一致,不同页返回的JSON字段顺序可能有细微差异,直接用rbind容易报错。
无正则清洗的稳定实现方案
直接解析页面内置的#__NEXT_DATA__结构化JSON数据是最稳的方案,所有字段都是网站直接返回的结构化结果,不需要手动清洗、不需要写复杂的CSS选择器,也不会因为页面样式调整失效,修正后的可运行代码如下:
# 加载依赖 library(rvest) library(dplyr) library(jsonlite) # 配置参数 max_page <- 5 # 自定义要抓取的最大页数 base_url <- "https://nomics.com/" datalist <- list() # 统一用这个列表存储每页结果 for(i in 1:max_page){ message("正在抓取第", i, "页数据") # 正确拼接当前页URL if(i == 1){ current_url <- base_url }else{ current_url <- paste0(base_url, "?page=", i) } # 读取页面并解析内置JSON page_json <- read_html(current_url) |> html_element('#__NEXT_DATA__') |> html_text() |> parse_json(simplifyVector = TRUE) # 提取需要的字段,可根据自己需求增减 # 可用字段包括rank(排名)、name(资产名)、symbol(代币符号)、price(价格)、market_cap(市值)、volume(24h交易量)、price_change_pct(涨跌幅)等 page_data <- page_json$props$pageProps$data$currenciesTicker |> select(rank, name, symbol, price, market_cap, volume, price_change_pct) datalist[[i]] <- page_data # 加2秒延时,避免请求太频繁被网站封禁 Sys.sleep(2) } # 合并所有页数据,bind_rows会自动对齐列名,比rbind兼容性好 crypto_data <- bind_rows(datalist) |> as_tibble() # 查看结果 head(crypto_data)
补充:其实交易所数据也可以用同样的方法解析内置JSON抓取,比写CSS选择器更稳定,不会因为网站更新样式类名就失效。
内容的提问来源于stack exchange,提问作者mkruisbrink
相关产品推荐
相关产品推荐

