如何用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
相关产品推荐
相关产品推荐

