You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言循环爬取亚马逊时轮换User Agent解决503拦截问题

问题原因

你现有代码全程固定使用单个UA,核心是两个问题:

  • R语言内置随机抽样函数为小写开头的sample(),原代码写的大写Sample()不存在,运行时不会执行随机抽取逻辑,会固定取UA列表的第一个值全程使用
  • 就算修正函数名,没有明确的轮换规则,每次请求随机跳UA的特征太异常,反而容易被亚马逊反爬识别,触发503拦截。
修正后代码

调整后实现固定间隔轮换UA,每爬35页切换一次,400页爬取过程中会轮换10次以上,满足至少更换2-3次UA的要求,同时加了拦截自动重试逻辑,降低被封概率:

library(rvest)
library(tidyverse)

# 抓取并清洗桌面端UA列表
ua_page <- read_html("https://developers.whatismybrowser.com/useragents/explore/hardware_type_specific/computer/")
ua_list <- ua_page %>% 
  html_nodes(".code") %>% 
  html_text(trim = TRUE) %>%
  # 过滤长度过短的无效UA
  discard(~nchar(.x) < 50)

df_monitors <- list()
# 配置UA轮换间隔:每35页换1次UA
rotate_interval <- 35
# 初始化第一个随机UA
current_ua <- sample(ua_list, 1)

for (i in 2:400) { 
  # 到达轮换间隔时,选一个和当前不同的新UA
  if (i %% rotate_interval == 0) {
    current_ua <- sample(ua_list[ua_list != current_ua], 1)
    print(paste("第", i, "页切换User Agent"))
  }
  
  # 失败重试逻辑:最多重试3次,每次失败自动换UA
  retry_count <- 0
  page <- NULL
  while(is.null(page) && retry_count < 3) {
    try({
      page <- read_html(
        paste0("https://www.amazon.it/s?i=computers&rh=n%3A460159031&fs=true&page=", i),
        user_agent = current_ua
      )
    }, silent = TRUE)
    if(is.null(page)) {
      retry_count <- retry_count + 1
      current_ua <- sample(ua_list[ua_list != current_ua], 1)
      Sys.sleep(2)
    }
  }
  
  if(is.null(page)) {
    print(paste("第", i, "页多次重试失败,跳过"))
    next
  }
  
  # 随机等待3-6秒,消除固定间隔的爬虫特征
  Sys.sleep(sample(3:6, 1))
  
  # 提取商品父节点
  monitors <- page  %>% html_nodes(xpath= "//div[@class='a-section a-spacing-small s-padding-left-small s-padding-right-small']")
  
  # 节点为空说明被拦截,换UA后跳过当前页
  if(length(monitors) == 0) {
    print(paste("第", i, "页返回内容异常,疑似被拦截,已切换UA"))
    current_ua <- sample(ua_list[ua_list != current_ua], 1)
    next
  }
  
  # 解析商品信息
  description <- monitors %>% html_node(xpath= ".//*[@class='a-size-base-plus a-color-base a-text-normal']") %>% html_text(trim = TRUE)
  price <- monitors %>% html_node(xpath= ".//*[@class='a-price-whole']") %>% html_text(trim = TRUE)
  
  df_monitors[[as.character(i)]] <- data.frame(description,price)
  print(paste("已完成爬取第", i, "页"))
}

# 合并全部结果
monitor_final <- bind_rows(df_monitors)
关键调整说明
  • 修正了原代码的函数名错误,确保UA抽取逻辑正常生效
  • 采用固定间隔轮换UA的规则,既满足多次更换UA的要求,也不会因为UA切换过于频繁触发反爬
  • 增加异常重试机制:碰到503报错、页面内容为空的拦截场景时,自动更换UA重试,避免单次拦截中断整个爬取任务
  • 将原固定4秒的等待改为3-6秒随机等待,消除规律访问的爬虫特征,进一步降低被拦截概率
  • 对抓取到的UA列表做基础清洗,过滤无效值,保证使用的UA都是有效的桌面端标识

内容的提问来源于stack exchange,提问作者Gio 255

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:45:45