- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试以编程方式搜索网站,但提交按钮功能似乎主要由 JavaScript 提供支持。我不太熟悉这是如何工作的,所以我可能是错的。
这是我正在使用的代码:
library(rvest)
BASE_URL = 'https://mdocweb.state.mi.us/otis2/otis2.aspx'
PARAMS = list(txtboxLName='Smith',
drpdwnGender='Either',
drpdwnRace='All',
drpdwnStatus='All',
submit='btnSearch')
# rvest approach
s = html_session(BASE_URL)
form = html_form(s)[[1]]
form = set_values(form, PARAMS)
resp = submit_form(s, form, submit='btnSearch') # This gives an error
# httr approach
resp = httr::POST(BASE_URL, body=PARAMS, encode='form')
html = httr::content(resp) # This just returns that same page I was on
<input type="submit" name="btnSearch" value="Search" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("btnSearch", "", true, "", "", false, false))" language="javascript" id="btnSearch" style="width:100px;">
onclick
属性,我未受过教育的假设是 JavaScript 的使用干扰了我的方法。但同样,我并不完全理解这一切是如何运作的,所以我可能是错的。
rvest
或
httr
,但不是
RSelenium
?另外,如果这可以在 Python 中实现,我也会接受。
最佳答案
我们首先需要获取原始搜索页面,因为这是一个共享站点(或类似站点),我们需要一些隐藏的表单字段以供稍后使用:
library(httr)
library(rvest)
library(tidyverse)
pre_pg <- read_html("https://mdocweb.state.mi.us/otis2/otis2.aspx")
setNames(
html_nodes(pre_pg, "input[type='hidden']") %>% html_attr("value"),
html_nodes(pre_pg, "input[type='hidden']") %>% html_attr("name")
) -> hidden
str(hidden)
## Named chr [1:3] "x62pLbphYWUDXsdoNdBBNrxqyHHI+K06BzjFwdP3Uooafgey2uG1gLWxzh07djRxiQR724uplZFAI8klbq6HCSkmrp8jP15EMwvkDM/biUEuQrf"| __truncated__ ...
## - attr(*, "names")= chr [1:3] "__VIEWSTATE" "__VIEWSTATEGENERATOR" "__EVENTVALIDATION"
POST
提交:
POST(
url = "https://mdocweb.state.mi.us/otis2/otis2.aspx",
add_headers(
Origin = "https://mdocweb.state.mi.us",
`User-Agent` = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.52 Safari/537.36",
Referer = "https://mdocweb.state.mi.us/otis2/otis2.aspx"
),
body = list(
`__EVENTTARGET` = "",
`__EVENTARGUMENT` = "",
`__VIEWSTATE` = hidden["__VIEWSTATE"],
`__VIEWSTATEGENERATOR` = hidden["__VIEWSTATEGENERATOR"],
`__EVENTVALIDATION` = hidden["__EVENTVALIDATION"],
txtboxLName = "Smith",
txtboxFName = "",
txtboxMDOCNum = "",
drpdwnGender = "Either",
drpdwnRace = "All",
txtboxAge = "",
drpdwnStatus = "All",
txtboxMarks = "",
btnSearch = "Search"
),
encode = "form"
) -> res
mcga <- function(x) {
x <- tolower(x)
x <- gsub("[[:punct:][:space:]]+", "_", x)
x <- gsub("_+", "_", x)
x <- gsub("(^_|_$)", "", x)
make.unique(x, sep = "_")
}
pg <- content(res, as="parsed")
<div>
s。但是,它以编程方式生成并且非常统一。我们不想输入太多,所以让我们先获取稍后将使用的列名:
col_names <- html_nodes(pg, "a.headings") %>% html_text(trim=TRUE) %>% mcga()
## [1] "offender_number" "last_name" "first_name"
## [4] "date_of_birth" "sex" "race"
## [7] "mcl_number" "location" "status"
## [10] "parole_board_jurisdiction_date" "maximum_date" "date_paroled"
xml2
📦 现在可以移除节点:
xml_find_all(pg, ".//div[@class='screenReaderOnly']") %>% xml_remove()
xml_find_all(pg, ".//span[@class='visible-phone']") %>% xml_remove()
<div>
“行”:
records <- html_nodes(pg, "div.offenderRow")
map(sprintf(".//div[@class='span1 searchCol%s']", 1:12), ~{
html_nodes(records, xpath=.x) %>% html_text(trim=TRUE)
}) %>%
set_names(col_names) %>%
bind_cols() %>%
readr::type_convert() -> xdf
xdf
## # A tibble: 25 x 12
## offender_number last_name first_name date_of_birth sex race mcl_number location status
## <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 544429 SMITH AARICK 12/03/1967 M White 333.74012D3 Gladwin Parole
## 2 210262 SMITH AARON 05/27/1972 M Black <NA> <NA> Dischrg
## 3 372965 SMITH AARON 09/16/1973 M White <NA> <NA> Dischrg
## 4 413411 SMITH AARON 07/13/1973 M Black <NA> <NA> Dischrg
## 5 618210 SMITH AARON 10/12/1984 M Black <NA> <NA> Dischrg
## 6 675823 SMITH AARON 05/19/1989 M Black 333.74032A5 Det Lahser Prob Prob
## 7 759548 SMITH AARON 06/19/1990 M Black <NA> <NA> Dischrg
## 8 763189 SMITH AARON 07/15/1976 M White 333.74032A5 Mt. Pleasant Prob
## 9 854557 SMITH AARON 12/27/1973 M White <NA> <NA> Dischrg
## 10 856804 SMITH AARON 02/24/1989 M White 750.110A2 Harrison CF Prison
## # ... with 15 more rows, and 3 more variables: parole_board_jurisdiction_date <chr>, maximum_date <chr>,
## # date_paroled <chr>
glimpse(xdf)
## Observations: 25
## Variables: 12
## $ offender_number <int> 544429, 210262, 372965, 413411, 618210, 675823, 759548, 763189, 854557, 85...
## $ last_name <chr> "SMITH", "SMITH", "SMITH", "SMITH", "SMITH", "SMITH", "SMITH", "SMITH", "S...
## $ first_name <chr> "AARICK", "AARON", "AARON", "AARON", "AARON", "AARON", "AARON", "AARON", "...
## $ date_of_birth <chr> "12/03/1967", "05/27/1972", "09/16/1973", "07/13/1973", "10/12/1984", "05/...
## $ sex <chr> "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M",...
## $ race <chr> "White", "Black", "White", "Black", "Black", "Black", "Black", "White", "W...
## $ mcl_number <chr> "333.74012D3", NA, NA, NA, NA, "333.74032A5", NA, "333.74032A5", NA, "750....
## $ location <chr> "Gladwin", NA, NA, NA, NA, "Det Lahser Prob", NA, "Mt. Pleasant", NA, "Har...
## $ status <chr> "Parole", "Dischrg", "Dischrg", "Dischrg", "Dischrg", "Prob", "Dischrg", "...
## $ parole_board_jurisdiction_date <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, "11/28/2024", "03/25/2016", NA, NA, NA...
## $ maximum_date <chr> NA, "09/03/2015", "06/29/2016", "10/02/2017", "05/19/2017", "07/18/2019", ...
## $ date_paroled <chr> "11/15/2016", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
type_convert
wld 提供了更好的转换,尤其是日期列,但它没有并且可能会被消除。
xml_integer(html_nodes(pg, "span#lblPgCurrent"))
## [1] 1
xml_integer(html_nodes(pg, "span#lblTotalPgs"))
## [1] 101
html_nodes(pg, "input[type='hidden']")
POST
只有那些隐藏字段和一个表单元素的调用:
btnNext = 'Next'
.您需要在分页结果集中的所有单个页面上重复此操作,然后最后
bind_rows()
一切。
library(httr)
library(rvest)
library(tidyverse)
mcga <- function(x) {
x <- tolower(x)
x <- gsub("[[:punct:][:space:]]+", "_", x)
x <- gsub("_+", "_", x)
x <- gsub("(^_|_$)", "", x)
make.unique(x, sep = "_")
}
start_search <- function(last_name) {
pre_pg <- read_html("https://mdocweb.state.mi.us/otis2/otis2.aspx")
setNames(
html_nodes(pre_pg, "input[type='hidden']") %>% html_attr("value"),
html_nodes(pre_pg, "input[type='hidden']") %>% html_attr("name")
) -> hidden
POST(
url = "https://mdocweb.state.mi.us/otis2/otis2.aspx",
add_headers(
Origin = "https://mdocweb.state.mi.us",
`User-Agent` = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.52 Safari/537.36",
Referer = "https://mdocweb.state.mi.us/otis2/otis2.aspx"
),
body = list(
`__EVENTTARGET` = "",
`__EVENTARGUMENT` = "",
`__VIEWSTATE` = hidden["__VIEWSTATE"],
`__VIEWSTATEGENERATOR` = hidden["__VIEWSTATEGENERATOR"],
`__EVENTVALIDATION` = hidden["__EVENTVALIDATION"],
txtboxLName = last_name,
txtboxFName = "",
txtboxMDOCNum = "",
drpdwnGender = "Either",
drpdwnRace = "All",
txtboxAge = "",
drpdwnStatus = "All",
txtboxMarks = "",
btnSearch = "Search"
),
encode = "form"
) -> res
content(res, as="parsed")
}
extract_results <- function(results_pg) {
col_names <- html_nodes(results_pg, "a.headings") %>% html_text(trim=TRUE) %>% mcga()
xml_find_all(results_pg, ".//div[@class='screenReaderOnly']") %>% xml_remove()
xml_find_all(results_pg, ".//span[@class='visible-phone']") %>% xml_remove()
records <- html_nodes(results_pg, "div.offenderRow")
map(sprintf(".//div[@class='span1 searchCol%s']", 1:12), ~{
html_nodes(records, xpath=.x) %>% html_text(trim=TRUE)
}) %>%
set_names(col_names) %>%
bind_cols()
}
current_page_number <- function(results_pg) {
xml_integer(html_nodes(results_pg, "span#lblPgCurrent"))
}
last_page_number <- function(results_pg) {
xml_integer(html_nodes(results_pg, "span#lblTotalPgs"))
}
scrape_status <- function(results_pg) {
cur <- current_page_number(results_pg)
tot <- last_page_number(results_pg)
message(sprintf("%s of %s", cur, tot))
}
next_page <- function(results_pg) {
cur <- current_page_number(results_pg)
tot <- last_page_number(results_pg)
if (cur == tot) return(NULL)
setNames(
html_nodes(results_pg, "input[type='hidden']") %>% html_attr("value"),
html_nodes(results_pg, "input[type='hidden']") %>% html_attr("name")
) -> hidden
POST(
url = "https://mdocweb.state.mi.us/otis2/otis2.aspx",
add_headers(
Origin = "https://mdocweb.state.mi.us",
`User-Agent` = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.52 Safari/537.36",
Referer = "https://mdocweb.state.mi.us/otis2/otis2.aspx"
),
body = list(
`__EVENTTARGET` = hidden["__EVENTTARGET"],
`__EVENTARGUMENT` = hidden["__EVENTARGUMENT"],
`__VIEWSTATE` = hidden["__VIEWSTATE"],
`__VIEWSTATEGENERATOR` = hidden["__VIEWSTATEGENERATOR"],
`__EVENTVALIDATION` = hidden["__EVENTVALIDATION"],
btnNext = 'Next'
),
encode = "form"
) -> res
content(res, as="parsed")
}
curr_pg <- start_search("smith")
results_df <- extract_results(curr_pg)
pb <- progress_estimated(last_page_number(curr_pg)-1)
repeat{
scrape_status(curr_pg) # optional esp since we have a progress bar
pb$tick()$print()
curr_pg <- next_page(curr_pg)
if (is.null(curr_pg)) break
results_df <- bind_rows(results_df, extract_results(next_pg))
Sys.sleep(5) # be kind
}
关于r - 如何使用 httr 或 rvest 提交似乎由 JavaScript 处理的表单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46224378/
谁能帮我解决这个问题?我有一个 Tomcat 和简单的 JSF 应用程序:https://github.com/gooamoko/jsfbilling/ .当我在 Tomcat 上运行应用程序时,它运
我有两个这样的域类,第一个是 Manager : package com.mnm class Manager { String name; static hasMany = [ pro
当我运行以下代码时,打印输出似乎不正确。 void thread_Calc(int *pos) { printf("recieved %d\n", *pos); sig = -1; man
这个问题在这里已经有了答案: How to access a local variable from a different function using pointers? (10 个答案) 关闭
我编写了一个程序,其中列表构建器方法返回 IEnumerable of string,其中包括大量字符串(100 万个项目),我将其存储在 List of string 中,然后它将所有项目附加到 中
我正在尝试编写一个 IRC 类型的聊天客户端,它具有可以连接到服务器的客户端。我试图让它在本地 atm 上工作(使用 FIFOS 而不是套接字)。 我遇到了以下我似乎无法解决的问题: 接受新的客户端连
我的一个 cronjobs 每天发送一封电子邮件 35 6 * * * cd $EZPUBLISHROOT && $PHP runcronjobs.php -q 2>&1 我停止使用 cron sud
我使用 WPF 打印路径来处理在我们的应用程序中创建的大型图表。整个图表由视觉效果组成。 所谓的“DesignerPaginator”对图表进行分页(非常简单)。 从这一点来说,我做了以下三件事: -
我尝试在更新之前跟踪系统应用程序并使用: public static boolean isSystemApplication(Context ctx, IContent content) {
我在这里附上了一个查询分析结果,https://explain.depesz.com/s/x9BN 这是查询 EXPLAIN ANALYZE SELECT branche
我正在做一个 CXF(spring) 项目 (HUB)。部署后,我可以看到肥皂和休息服务列表,我通过两个地址打开它。一种是使用本地主机,第二种是使用我电脑的 ip。所以我得到了这些输出。 使用本地主机
这是一个 AnyHashable 不支持枚举转换的简单案例。 enum testEnum: String { case Test } let myObject: AnyHashable = t
我的主要目标是比较存储在数据库和 XLSX 文件中的数据。 为此,我按以下方式创建了两个列表: private class ProductList { public string produc
我从 CMake 3.6 更新到任何最新版本 (3.12.0-rc2),现在我的一个程序无法编译。 奇怪的是,错误消息显示了标准库本身中的 undefined symbol 。这是错误消息: Unde
我希望将我的自定义对话框动画化为从特定点出现,但我无法为对话框设置动画。 该对话框是一个基本的 RelativeLayout,设置为 extends Dialog 类中的布局。 正如这里的一些答案所建
我已经在这个论坛上调查过很多类似的问题,但似乎没有一个能解决我的问题。 我会在底部列出我在这个论坛上看到的一些问题页面,但让我先谈谈我对这个问题的看法。 我正在使用 codeigniter v 2.x
我正在尝试在 RHEL 7 上启动一个 docker-compose 项目作为 systemd 服务。这是我的 systemd 脚本 (/etc/systemd/system/wp.service):
这个问题已经有答案了: "Notice: Undefined variable", "Notice: Undefined index", "Warning: Undefined array key",
我正在尝试在 RHEL 7 上启动一个 docker-compose 项目作为 systemd 服务。这是我的 systemd 脚本 (/etc/systemd/system/wp.service):
此问题出现在my last question here之后。我想将每个按钮聚焦和失去焦点背景设置为主菜单(ContentPane 即 JPanel)下方的背景颜色,因此按钮看起来像选项卡。它在不同的环
我是一名优秀的程序员,十分优秀!