R语言rvest爬取亚马逊50个商品仅获取前30条数据的解决方法
问题原因
你只能提取到30条商品的核心原因是亚马逊畅销榜页面采用了懒加载机制:页面首次返回的静态HTML只渲染前30条商品信息,剩余20条需要页面滚动到对应位置时才会通过接口动态插入到DOM中。rvest::read_html()只能抓取初始请求返回的静态源码,自然拿不到后续动态加载的内容。
另外你原代码直接提取整个grid容器的文本再按#拆分的逻辑容错率很低,一旦商品标题、描述里包含#字符就会拆分错位,建议直接定位单个商品的独立节点做解析。
解决方法
优先选第一种方案,最轻量不需要安装复杂依赖:
方法1:直接分页爬取(推荐)
亚马逊这类畅销榜默认单页展示30条商品,你要的50条刚好分布在第1、2页,直接修改URL里的pg参数分别爬取两页,合并去重后取前50条即可,不需要处理动态渲染。
注意爬取时要带上合法的User-Agent请求头,不然很容易被亚马逊反爬拦截,返回空内容或者403错误。
参考代码:
library(rvest) library(dplyr) # 封装单页爬取逻辑 get_zgbs_products <- function(page_num) { # 拼接对应分页的URL page_url <- paste0( "https://www.amazon.com/Best-Sellers-Industrial-Scientific-3D-Printers/zgbs/industrial/6066127011/ref=zg_bs_pg_", page_num, "?_encoding=UTF8&pg=", page_num ) # 携带浏览器UA发起请求 page <- read_html( page_url, httr::user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36") ) # 定位每个独立商品卡片节点,避免文本拆分错误 item_nodes <- page %>% html_elements("div#gridItemRoot") # 按需提取字段,示例提取排名、标题、价格 data.frame( rank = item_nodes %>% html_element("span.zg-bdg-text") %>% html_text2(), title = item_nodes %>% html_element("div._cDEzb_p13n-sc-css-line-clamp-3_g3dy1") %>% html_text2(), price = item_nodes %>% html_element("span._cDEzb_p13n-sc-price_3mJ9Z") %>% html_text2() ) } # 爬取前两页,合并去重后取前50条即为全量商品 all_products <- bind_rows(get_zgbs_products(1), get_zgbs_products(2)) %>% distinct(rank, .keep_all = TRUE) %>% # 按排名去重,避免两页衔接位置重复 head(50)
爬取注意事项:
- 两次分页请求之间可以加
Sys.sleep(2~3)停顿几秒,不要请求过于频繁,降低被反爬拦截的概率 - 如果后续页面结构调整导致CSS选择器失效,直接在浏览器开发者工具里检查元素更新选择器即可
方法2:模拟浏览器触发懒加载(单页抓取场景用)
如果非要在单页内拿全50条,可以借助支持浏览器渲染的工具模拟人工滚动页面,等所有懒加载内容渲染完成后再提取源码解析,常用的轻量工具是chromote包(基于Chrome DevTools协议,不需要额外装Java环境)。
核心逻辑参考:
library(chromote) library(rvest) # 启动Chrome会话 chrome <- ChromoteSession$new() # 打开目标页面 chrome$Page$navigate("https://www.amazon.com/Best-Sellers-Industrial-Scientific-3D-Printers/zgbs/industrial/6066127011/ref=zg_bs_pg_1?_encoding=UTF8&pg=1") Sys.sleep(2) # 等初始页面加载 # 分段滚动到页面底部,触发所有懒加载 chrome$Runtime$evaluate("window.scrollTo(0, document.body.scrollHeight/2)") Sys.sleep(2) chrome$Runtime$evaluate("window.scrollTo(0, document.body.scrollHeight)") Sys.sleep(3) # 等剩余商品加载完成 # 提取渲染完成的完整页面源码 full_page_html <- chrome$Runtime$evaluate("document.documentElement.outerHTML")$result$value chrome$close() # 关闭浏览器会话 # 后续解析逻辑和方法1一致 web <- read_html(full_page_html) item_nodes <- web %>% html_elements("div#gridItemRoot") # 再提取你需要的字段即可
内容的提问来源于stack exchange,提问作者anderwyang
相关产品推荐
相关产品推荐

