You need to enable JavaScript to run this app. 如何用R提取NOAA潮汐站页面含站点ID的抬头文本?
优惠活动
大模型
产品
解决方案
定价
更多

如何用R提取NOAA潮汐站页面含站点ID的抬头文本?

需求目标

我尝试使用R语言爬取网页NOAA站点页面的文本内容,核心需求是获取包含站点编号的抬头文本Bridgeport, CT - Station ID: 8467150。已对页面截图标注目标文本位置,该文本在浏览器元素检查面板中处于高亮状态。
目标网页截图,所需文本为高亮黄色部分,已在元素检查面板中选中
此前使用readLines()方法获取页面全量文本,网站近期更新后该方法无法抓取到目标内容,站点名称与编号无法被readLines()识别,示例代码如下:

url <- "https://tidesandcurrents.noaa.gov/stationhome.html?id=8467150"
stn <- "8467150"

webpage <- readLines(url, warn = FALSE)

### grep结果显示爬取到的文本中不存在站点编号
grep(x = webpage, pattern = stn, value = TRUE)
已尝试的方案

我需要寻找新的方法获取目标文本,已尝试的内容如下:

  • 使用httr包发起请求,仍然无法将页面的全部HTML文本纳入爬取结果,示例代码:
### 使用httr的尝试代码
hDat <- httr::RETRY("GET", url, times = 10)
txt  <- httr::content(hDat, "text")

### grep结果显示仍无法检索到站点编号
grep(x = txt, pattern = stn, value = TRUE)
  • 考虑使用XML与rvest包,但不确定如何定位对应的CSS选择器或XPath表达式,示例代码:
### 使用XML的部分尝试代码
h  <- xml2::read_html(url)
h2 <- XML::htmlTreeParse(h, useInternalNodes=TRUE, asText = TRUE)

### 该方案可能可行,但不确定如何定位正确的路径
html.parse <- XML::xpathApply(h2, path = "div.span8", XML::xmlValue)

无论采用何种方案,需要获取包含站点名称与编号的抬头文本的可行实现方法。


解决方案

核心原因

站点更新后,目标抬头文本不再包含在初始返回的静态HTML中,属于前端脚本动态渲染生成的内容;同时缺少合规请求头会被站点反爬机制拦截,返回缺失动态内容的降级页面,因此静态爬取方法无法检索到对应文本。

可运行实现代码

方案1:带合规请求头的rvest爬取

模拟浏览器请求头绕过基础反爬机制,通过CSS选择器定位目标节点:

library(httr)
library(rvest)

url <- "https://tidesandcurrents.noaa.gov/stationhome.html?id=8467150"
stn <- "8467150"

# 构造浏览器请求头,避免被反爬拦截
req_headers <- add_headers(
  `User-Agent` = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
  `Accept` = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
)

# 发起重试请求
resp <- RETRY("GET", url, times = 10, req_headers)

# 解析页面提取目标抬头文本
target_text <- read_html(resp) %>%
  html_element(css = "h1.page-title") %>%
  html_text(trim = TRUE)

# 验证结果
target_text
# 输出:[1] "Bridgeport, CT - Station ID: 8467150"

方案2:调用官方元数据API(稳定性最高)

无需处理页面渲染逻辑,直接获取站点结构化元数据,不受前端页面更新影响:

# 构造API请求地址
api_url <- sprintf("https://api.tidesandcurrents.noaa.gov/mdapi/prod/webapi/stations/%s.json", stn)

# 发起请求获取元数据
api_resp <- RETRY("GET", api_url, times = 10)
station_info <- content(api_resp, as = "parsed")$features[[1]]$properties

# 拼接生成目标抬头文本
target_text <- sprintf(
  "%s, %s - Station ID: %s",
  station_info$name,
  station_info$state,
  stn
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 09:06:06