这是a prior thread的后续行动。代码对于单个值工作得非常好,但是当我尝试传递多于1个值时出现以下错误我根据函数的长度得到错误。 vapply出错(元素,编码,字符(1)): 值必须是长度1, 但是FUN(X [1])结果是长度3
以下是代码示例。在大多数情况下,我只能命名一个对象并刮擦那个方式。
library(httr)
library(rvest)
library(dplyr)
b<-c('48127','48180','49504')
POST(
url = "http://www.nearestoutlet.com/cgi-bin/smi/findsmi.pl",
body = list(zipcode = b),
encode = "form"
) -> res
我想知道将值插入表单的循环是否是正确的方法?然而,我的循环写作技巧仍处于开发阶段,我不确定将它放在何处;另外,当我调用循环时,它不会逐行打印,只返回null结果。
#d isn't listed in the above code as it returns null
d<-for(i in 1:3){nrow(b)}
答案 0 :(得分:1)
这是一种发送多个POST请求的方法
library(httr)
library(rvest)
b <- c('48127','48180','49504')
对于b中的每个元素,执行一个将发送相应POST请求的函数
res <- lapply(b, function(x){
res <- POST(
url = "http://www.nearestoutlet.com/cgi-bin/smi/findsmi.pl",
body = list(zipcode = x),
encode = "form"
)
res <- read_html(content(res, as="raw"))
})
现在对于列表res
的每个元素,您应该执行hrbrmstr解释的解析步骤:How can I Scrape a CGI-Bin with rvest and R?
library(tidyverse)
我将使用hrbrmstr的代码,因为他是国王,你已经清楚了。我们在这里所做的只是在res
列表的每个元素上执行它。
res_list = lapply(res, function(x){
rows <- html_nodes(x, "table[width='300'] > tr > td")
ret <- data_frame(
record = !is.na(html_attr(rows, "bgcolor")),
text = html_text(rows, trim=TRUE)
) %>%
mutate(record = cumsum(record)) %>%
filter(text != "") %>%
group_by(record) %>%
summarise(x = paste0(text, collapse="|")) %>%
separate(x, c("store", "address1", "city_state_zip", "phone_and_or_distance"), sep="\\|", extra="merge")
return(ret)
}
)
或使用map
purrr
res %>%
map(function(x){
rows <- html_nodes(x, "table[width='300'] > tr > td")
data_frame(
record = !is.na(html_attr(rows, "bgcolor")),
text = html_text(rows, trim=TRUE)
) %>%
mutate(record = cumsum(record)) %>%
filter(text != "") %>%
group_by(record) %>%
summarise(x = paste0(text, collapse="|")) %>%
separate(x, c("store", "address1", "city_state_zip", "phone_and_or_distance"),
sep="\\|", extra="merge") -> ret
return(ret)
}
)
如果你想在数据框中这样做:
res_df <- data.frame(do.call(rbind, res_list), #rbinds list elements
b = rep(b, times = unlist(lapply(res_list, length)))) #names the rows according to elements in b
答案 1 :(得分:0)
您可以将值放在帖子中,如下所示
b<-c('48127','48180','49504')
for(i in 1:length(b)) {
POST(
url = "http://www.nearestoutlet.com/cgi-bin/smi/findsmi.pl",
body = list(zipcode =b[i]),
encode = "form"
) -> res
# YOUR CODES HERE (for getting content of the page etc.)
}
但是因为对于每个不同的邮政编码值,&#34; res&#34;值将有所不同,您需要将其余代码放在我评论的区域内。否则你只得到最后一个值。