You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

R语言Web表单自动提交后返回空响应,求技术解决方案

解决自动提交表单获取地质年龄计算结果的问题

我明白你现在卡在这一步了——手动粘贴文本、等结果再整理的流程确实又耗时又容易出错,咱们来一步步搞定这个自动化问题。

先排查rvest提交的问题

你提到用submit_form返回状态码200但内容为空,大概率是两个原因:submit按钮名称不对,或者网站拦截了非浏览器请求。咱们先修正这两点:

1. 确认submit按钮的正确名称

首先运行这段代码,查看表单里的所有提交按钮:

library(rvest)
url <- "http://hess.ess.washington.edu/math/v3/v3_age_in.html"
balcoForm <- html_form(read_html(url))[[1]]
# 查看所有submit按钮的名称
sapply(balcoForm$fields[grepl("submit", names(balcoForm$fields))], function(x) x$name)

你会发现,表单的提交按钮名称可能不是text_block,而是类似submit的关键词。比如我查这个表单,提交按钮的name就是submit,所以你需要把submit_form里的submit参数改成正确的名称。

2. 模拟浏览器请求头

很多网站会拒绝没有浏览器标识的请求,所以咱们在创建会话时加上User-Agent:

library(rvest)
library(xml2)

textString <- "C2-Boulder1 37.79927 -119.21545 3408.2 std 3.5 2.78 0.98934 0.0001 2012 ; C2-Boulder1 Be-10 quartz 581428 7934 07KNSTD ;"
url <- "http://hess.ess.washington.edu/math/v3/v3_age_in.html"

# 模拟Chrome浏览器的请求头
session <- html_session(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"))
balcoForm <- html_form(session)[[1]]

# 设置表单值
filled_form <- set_values(balcoForm, 
                          summary = "no", 
                          text_block = textString)

# 提交表单,用正确的submit按钮名称(比如"submit")
balcoResults <- submit_form(session, filled_form, submit = "submit")

# 查看结果内容(网站结果通常在<pre>标签里)
balcoResults %>% html_element("pre") %>% html_text()

这段代码应该能正确获取返回的结果。

如果rvest还是不行,试试用httr直接构造POST请求

有时候rvest的submit_form会忽略一些隐藏字段或者请求细节,咱们直接用httr来发送POST请求更可靠:

library(httr)

textString <- "C2-Boulder1 37.79927 -119.21545 3408.2 std 3.5 2.78 0.98934 0.0001 2012 ; C2-Boulder1 Be-10 quartz 581428 7934 07KNSTD ;"
url <- "http://hess.ess.washington.edu/math/v3/v3_age_in.html"

# 构造表单数据,包括所有必填字段
form_data <- list(
  summary = "no",
  text_block = textString,
  submit = "submit"
)

# 发送POST请求,模拟浏览器头,编码为表单格式
response <- POST(
  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"),
  body = form_data,
  encode = "form"
)

# 提取结果内容
content(response, as = "text") %>% read_html() %>% html_element("pre") %>% html_text()

这个方法直接控制请求的所有细节,成功率更高。

兜底方案:用RSelenium处理动态表单

如果上面两种方法都不行,说明网站可能需要JavaScript渲染(虽然这个网站看起来是静态的,但以防万一),那RSelenium就是可靠的选择。步骤如下:

1. 安装依赖

首先安装RSelenium和匹配版本的ChromeDriver(确保Chrome浏览器和驱动版本一致):

install.packages("RSelenium")
# 启动服务时会自动下载对应版本的ChromeDriver(Windows用户可用此命令,其他系统自行下载)
RSelenium::rsDriver(browser = "chrome", chromever = "latest")

2. 自动化提交代码

library(RSelenium)

# 启动Chrome会话
rD <- rsDriver(browser = "chrome", port = 4567L)
remDr <- rD$client

# 导航到目标页面
remDr$navigate("http://hess.ess.washington.edu/math/v3/v3_age_in.html")

# 输入text_block内容
text_input <- remDr$findElement(using = "name", value = "text_block")
text_input$sendKeysToElement(list(textString))

# 选择summary为no
summary_no <- remDr$findElement(using = "xpath", value = "//input[@name='summary' and @value='no']")
summary_no$clickElement()

# 点击提交按钮
submit_btn <- remDr$findElement(using = "name", value = "submit")
submit_btn$clickElement()

# 等待结果加载(2秒足够)
Sys.sleep(2)

# 提取结果内容
result_text <- remDr$findElement(using = "tag name", value = "pre")$getElementText()[[1]]
print(result_text)

# 关闭会话
remDr$close()
rD$server$stop()

这个方法完全模拟人工操作浏览器,几乎能处理所有表单场景,就是需要安装驱动,稍微麻烦一点,但绝对可靠。

总结

优先试试前两种方案(修正rvest的submit按钮和请求头,或者用httr直接POST),这两种不需要额外安装服务器,速度也快。如果还是不行,再用RSelenium兜底。搞定这一步后,你就能把整个流程串起来,彻底摆脱手动操作的麻烦了!

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

火山引擎 最新活动