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

如何为R语言迭代式网页爬虫脚本添加请求头解决403错误

R爬虫爬Trustpilot遇403错误:正确添加请求头及批量爬取方案

问题核心

爬取Trustpilot多页评论时,因无请求头的批量请求被网站反爬机制拦截,触发HTTP error 403;尝试两种添加请求头的方式均报错,需明确批量爬取场景下请求头的正确添加位置及方式。

之前尝试的错误分析

  1. 预先GET请求传入爬虫函数的错误
    你把GET()返回的响应对象直接传给爬虫函数,但函数大概率期望接收URL字符串,导致后续字符串拼接时出现类型不匹配,触发stri_c的类型强制转换警告。GET()返回的是response对象,并非纯URL字符串,不能直接当作参数传入处理页面内容的函数。

  2. 生成URL列表时嵌入GET请求的错误
    语法逻辑完全错误:str_c是用来拼接字符串的工具,不能将GET请求嵌入其中生成URL列表;同时GET()的参数格式也不符合语法要求,正确的流程是先生成纯URL字符串列表,再对每个URL发起请求。

正确解决方案

1. 封装带合法请求头的页面获取函数

先写一个通用函数,确保每次请求都携带模拟浏览器的请求头,同时处理响应状态:

library(httr)
library(rvest)
library(dplyr)
library(purrr)

# 封装带请求头的页面获取函数
get_trustpilot_page <- function(page_url) {
  # 构造模拟浏览器的请求头,可根据需求调整User-Agent
  request_headers <- add_headers(
    `User-Agent` = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
    `Accept` = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    `Referer` = "https://www.trustpilot.com/"
  )
  
  # 发送请求并设置超时
  response <- GET(page_url, request_headers, timeout(10))
  
  # 检查响应状态,失败则返回空并抛出警告
  if (status_code(response) != 200) {
    warning(paste("请求失败:URL=", page_url, "状态码=", status_code(response)))
    return(NULL)
  }
  
  # 返回解析后的HTML文档
  return(read_html(response))
}

2. 批量生成纯URL字符串列表

先生成所有需要爬取的页面URL,这里不要执行请求操作:

# 目标品牌基础URL
base_url <- "https://www.trustpilot.com/review/www.travelocity.com"
# 生成1到417页的URL列表
page_urls <- paste0(base_url, "?page=", 1:417)

3. 遍历URL批量爬取,添加反爬延迟

遍历每个URL时调用请求函数,同时添加随机延迟避免请求频率过高,再解析评论数据:

# 单页评论解析函数(需根据页面实际HTML结构调整选择器)
scrape_single_page <- function(html_doc, brand_name) {
  if (is.null(html_doc)) return(tibble())
  
  html_doc %>%
    html_elements(".review-card") %>%
    map_dfr(function(card) {
      tibble(
        brand = brand_name,
        review_title = card %>% html_element(".review-content__title") %>% html_text2(),
        review_content = card %>% html_element(".review-content__text") %>% html_text2(),
        star_rating = card %>% html_element(".star-rating") %>% html_attr("data-rating") %>% as.integer(),
        review_date = card %>% html_element(".review-content-header__dates") %>% html_text2()
      )
    })
}

# 批量爬取所有页面
all_reviews <- map_dfr(page_urls, function(url) {
  # 随机延迟1-3秒,降低请求频率
  Sys.sleep(runif(1, 1, 3))
  page_html <- get_trustpilot_page(url)
  scrape_single_page(page_html, "travelocity")
})

4. 额外反爬优化建议

  • 请求头多样化:如果爬取量极大,可准备多个User-Agent,每次请求随机挑选一个。
  • 403重试机制:在get_trustpilot_page函数中添加重试逻辑,比如遇到403时等待5-10秒后重试2-3次。
  • 遵守robots规则:提前查看Trustpilot的robots.txt,确认是否允许爬取评论页面,避免违反网站协议。

小范围爬取正常的原因

小批量请求(1-50页)的频率未触发网站反爬阈值,而417页的请求量超过了Travelocity对应的阈值(不同域名的反爬阈值可能不同,Expedia的288页刚好在阈值内),因此触发403拦截。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:18:18