当 rvest 无法识别提交按钮时提交 POST 表单
Posted
技术标签:
【中文标题】当 rvest 无法识别提交按钮时提交 POST 表单【英文标题】:Submit POST form when rvest doesn't recognize submit button 【发布时间】:2019-01-31 05:26:44 【问题描述】:我想提交以下表格(点击链接“Kliknite na ...”后会显示该表格): http://www1.biznet.hr/HgkWeb/do/extlogon
我必须输入一个名为“OIB”的参数,然后单击“Trazi”提交表单。
这是我的代码:
library(httr)
library(rvest)
sess <- html_session("http://www1.biznet.hr/HgkWeb/do/extlogon")
search_page <- sess %>%
follow_link(1)
form <- html_form(search_page)[[6]]
fill_form <- set_values(form, 'clanica.cla_oib' = '94989605030')
firma_i <- submit_form(search_page, fill_form, submit = 'submit')
最后一行产生错误:
错误:未知的提交名称“提交”。可能的值: clanica.asTextDatumGasenjaTo, clanica.asTextUdr_id
我不明白为什么 rvest 在不包含提交名称或类型的情况下将这两个参数识别为提交按钮。为什么 rvest 不将提交按钮“Trazi”识别为提交参数?总之,如何更改已填写的表单以执行表单?
【问题讨论】:
【参考方案1】:问题是一些输入错过了type
attr,而rvest
没有适当地检查这个。
为了说明问题:
library(httr)
library(rvest)
#> Loading required package: xml2
sess <- html_session("http://www1.biznet.hr/HgkWeb/do/extlogon")
search_page <- sess %>%
follow_link(1)
#> Navigating to /HgkWeb/do/extlogon;jsessionid=88295900F3F932C85A25BB18F326BE28
form <- html_form(search_page)[[6]]
fill_form <- set_values(form, 'clanica.cla_oib' = '94989605030')
某些字段没有type
属性:
sapply(fill_form$fields, function(x) '['(x, 'type'))
#> $clanica.limitSearchToActiveCompany.type
#> [1] "radio"
#>
#> $clanica.limitSearchToActiveCompany.type
#> [1] "radio"
#>
#> $joinBy.useInnerJoin.type
#> [1] "checkbox"
#>
#> $nazivTvrtke.type
#> [1] "text"
#>
#> $nazivZapocinjeSaPredanomVrijednoscu.type
#> [1] "checkbox"
#>
#> $clanica.cla_jmbp.type
#> [1] "text"
#>
#> $clanica.cla_mbs.type
#> [1] "text"
#>
#> $clanica.cla_oib.type
#> [1] "text"
#>
#> $asTextKomoraId.NA
#> NULL
#>
#> $clanica.asTextOpc_id.NA
#> NULL
#>
#> $clanica.cla_opcina.type
#> [1] "hidden"
#>
#> $clanica.asTextNas_id.NA
#> NULL
#>
#> $clanica.cla_naselje.type
#> [1] "hidden"
#>
#> $clanica.pos_id.NA
#> NULL
#>
#> $clanica.postaNaziv.type
#> [1] "hidden"
#>
#> $clanica.cla_ulica.type
#> [1] "text"
#>
#> $clanica.asTextDatumUpisaFrom.type
#> [1] "text"
#>
#> $clanica.asTextDatumUpisaTo.type
#> [1] "text"
#>
#> $clanica.asTextDatumGasenjaFrom.type
#> [1] "text"
#>
#> $clanica.asTextDatumGasenjaTo.type
#> [1] "text"
#>
#> $clanica.asTextUdr_id.NA
#> NULL
#>
#> $clanica.asTextVel_id.NA
#> NULL
#>
#> $nkd2007.type
#> [1] "text"
#>
#> $nkd2007PretrazivanjePoGlavnojDjelatnosti.type
#> [1] "radio"
#>
#> $nkd2007PretrazivanjePoGlavnojDjelatnosti.type
#> [1] "radio"
#>
#> $submit.type
#> [1] "submit"
#>
#> $org.apache.struts.taglib.html.CANCEL.type
#> [1] "submit"
#>
#> $orderBy.order1.NA
#> NULL
#>
#> $orderBy.order2.NA
#> NULL
#>
#> $limit.type
#> [1] "text"
#>
#> $searchForRowCount.type
#> [1] "checkbox"
#>
#> $joinBy.gfiGodina.NA
#> NULL
#>
#> $joinBy.gfiBrojZaposlenihFrom.type
#> [1] "text"
#>
#> $joinBy.gfiBrojZaposlenihTo.type
#> [1] "text"
#>
#> $joinBy.gfiUkupniPrihodFrom.type
#> [1] "text"
#>
#> $joinBy.gfiUkupniPrihodTo.type
#> [1] "text"
这弄乱了内部函数submit_request
,特别是其中的Filter()
。
它被引用了here,并且在this PR 中提出了一个修复,但它自 2016 年 7 月以来一直没有被合并,所以不要屏住呼吸。
PR 中的修复主要检查 type
attr 是否存在:
# form.R, row 280
is_submit <- function(x) 'type' %in% names(x) &&
tolower(x$type) %in% c("submit", "image", "button")
为了快速修复,您可以更改您拥有的数据,用随机类型覆盖 NULL
attr:
fill_form$fields <- lapply(fill_form$fields, function(x)
null_type = is.null(x$type)
if (null_type) x$type = 'text'
x
)
firma_i <- submit_form(search_page, fill_form, submit = 'submit')
firma_i
#> <session> http://www1.biznet.hr/HgkWeb/do/fullSearchPost
#> Status: 200
#> Type: text/html;charset=UTF-8
#> Size: 4366
由reprex package (v0.2.0) 于 2018 年 8 月 27 日创建。
【讨论】:
以上是关于当 rvest 无法识别提交按钮时提交 POST 表单的主要内容,如果未能解决你的问题,请参考以下文章
当引导验证成功时,如何使用 $.post 提交表单而不进行页面重定向?