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

如何在rvest的html_session中使用POST方法获取完整评论

解决TripAdvisor评论展开的POST请求问题(rvest+httr实现)

先呼应一下你提到的合规问题——确实TripAdvisor的使用条款禁止爬取,咱们就纯从技术角度探讨POST请求的实现哈!

你现在遇到的POST请求返回空body的问题,核心原因是请求参数、请求头或会话配置不完整,TripAdvisor的反爬机制会校验多个细节,加上两个POST请求存在依赖关系,必须按顺序在同一会话中发送。下面一步步给你梳理解决方案:

1. 理清两个POST请求的依赖关系

从你观察的网络流量来看:

  • 第一个POST是前置校验请求,用于验证会话合法性,触发评论展开的前置逻辑;
  • 第二个POST才是核心数据请求,返回完整的评论内容;
  • 两个请求必须共享同一个会话(Cookie),否则服务器会拒绝返回有效内容。

2. 关键配置修正要点

(1)复用会话保持Cookie

必须用html_session初始化会话,所有请求都通过这个会话发送,确保Cookie自动传递——TripAdvisor会严格校验会话的一致性。

(2)完善请求头

TripAdvisor会校验以下关键请求头,必须和抓包结果一致:

  • Referer:必须是原页面URL;
  • X-Requested-With:固定为XMLHttpRequest(标识AJAX请求);
  • Accept:匹配服务器预期的响应类型;
  • User-Agent:尽量用真实浏览器的UA,避免被识别为爬虫。

(3)正确编码请求体

你之前用encode="raw"是错误的,TripAdvisor的POST请求采用application/x-www-form-urlencoded编码,应该用encode="form",或者将参数整理为列表(httr会自动编码)。

3. 修正后的完整代码示例

library(rvest)
library(httr)

# 原页面URL
base_url <- "https://www.tripadvisor.com/Hotel_Review-g33657-d85704-Reviews-Hotel_Bristol-Steamboat_Springs_Colorado.html"

# 初始化会话,获取必要的Cookie和页面上下文
session <- html_session(
  base_url,
  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")
)

# 第一个POST请求(前置校验)
first_post_url <- "https://www.tripadvisor.com/OverlayWidgetAjax?Mode=EXPANDED_HOTEL_REVIEWS_RESP&metaReferer="
first_post_body <- list(
  reviews = "556957481,511497076,556144452,554686822,548218482",
  contextChoice = "DETAIL_HR",
  haveJses = "earlyRequireDefine,amdearly,global_error,long_lived_global,apg-Hotel_Review,apg-Hotel_Review-in,bootstrap,desktop-rooms-guests-dust-en_US,responsive-calendar-templates-dust-en_US,taevents",
  haveCsses = "apg-Hotel_Review-in",
  Action = "install"
)

# 发送第一个请求,复用会话
first_response <- POST(
  url = first_post_url,
  config = list(referer = base_url),
  body = first_post_body,
  encode = "form",
  add_headers(
    "X-Requested-With" = "XMLHttpRequest",
    "Accept" = "*/*"
  ),
  session = session
)

# 第二个POST请求(获取完整评论,URL和参数需与抓包完全匹配)
second_post_url <- "https://www.tripadvisor.com/OverlayWidgetAjax?Mode=EXPANDED_HOTEL_REVIEWS_RESP&metaReferer=Hotel_Review-g33657-d85704-Reviews-Hotel_Bristol-Steamboat_Springs_Colorado.html"
second_post_body <- list(
  widgetId = "EXPANDED_HOTEL_REVIEWS", # 从抓包中提取的关键参数
  reviews = "556957481,511497076,556144452,554686822,548218482",
  contextChoice = "DETAIL_HR",
  Action = "refresh"
)

# 发送第二个请求,复用会话
second_response <- POST(
  url = second_post_url,
  config = list(referer = base_url),
  body = second_post_body,
  encode = "form",
  add_headers(
    "X-Requested-With" = "XMLHttpRequest",
    "Accept" = "text/html, */*; q=0.01"
  ),
  session = session
)

# 解析完整评论内容
full_reviews <- content(second_response, "html") %>% 
  html_elements(".partial_entry") %>% 
  html_text(trim = TRUE)

print(full_reviews)

4. 额外排查技巧

如果仍然返回空响应,建议:

  • 用httr::verbose()添加到请求中,打印完整的请求/响应细节,和抓包结果逐一对比;
  • 检查抓包时的所有参数(包括隐藏参数,比如widgetId、pageNumber)是否完全复制;
  • 确认会话中的Cookie是否和浏览器中的一致(可以用session$cookies查看)。

再次强调:以上内容仅为技术探讨,实际使用请严格遵守TripAdvisor的使用条款!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:51:50