在R中使用两个不同的ID进行Web抓取

在R中使用两个不同的ID进行Web抓取,r,xml,loops,web-scraping,R,Xml,Loops,Web Scraping,我可以一次成功地刮取一个id。也许作为R的新手,单独刮取它们并在之后合并它们是很简单的,但我真的很想知道我是否可以做一个循环并自动完成。网站的格式是相同的,但每个ID的长度不同(但这不是本例中的问题) 这是我的代码,如果我只需要一个id: library(XML) library(rvest) library(plyr) library(dplyr) library(httr) library(data.table) library(pipeR) library(xml2) url <-

我可以一次成功地刮取一个id。也许作为R的新手,单独刮取它们并在之后合并它们是很简单的,但我真的很想知道我是否可以做一个循环并自动完成。网站的格式是相同的,但每个ID的长度不同(但这不是本例中的问题)

这是我的代码,如果我只需要一个id:

library(XML)
library(rvest)
library(plyr)
library(dplyr)
library(httr)
library(data.table)
library(pipeR)
library(xml2)

url <- "XXXXXXXXXXX"
session <-html_session(url)
form  <-html_form(read_html(url))[[1]]
filled_form <- set_values(form,
                          "id" = "S1",
                          "start" = "2017-01-17",
                          "end" = "2017-02-03",
                          "Password" = "lll")
s <- submit_form(session,filled_form)
z = read_xml(s$response)
z1 = as_list(z)
z2 <-z1[which(names(z1)=="scheduleList")]

result <- data.frame()
for (i in 2:length(z2[[1]])){               
      row <- cbind(
        teacher=z2[[1]][[1]][[1]][[1]],   
        t_id=attr(z2[[1]][[1]],"id"), 
        Date=attr(z2[[1]][[i]],"date"),     
        class=z2[[1]][[i]][[1]][[1]][[1]][[1]],
        c_id=attr(z2[[1]][[i]][[1]][[1]],"id"), 
        c_status=attr(z2[[1]][[i]][[1]][[1]],"status"),
        score=attr(z2[[1]][[i]][[1]],"id"),            
        People=z2[[1]][[i]][[1]][[1]][[2]][[1]],    
        department=z2[[1]][[i]][[1]][[1]][[3]][[1]][[1]],        
        d_id=attr(z2[[1]][[i]][[1]][[1]][[3]],"id")   
      )
      result <- rbind(result, row)
}
网站上S1的xml格式:

<result status="success">
  <code>1</code>
  <note>success</note>
  <scheduleList from="2017-01-17" to="2017-02-03">
    <teacher id="S1">
      <name>Mary</name>
    </teacher>
    <schedule date="2017-01-18">
      <score id="1">
        <class id="312" status="-4">
          <name>312C</name>
          <people>129</people>
          <department id="302f">
            <name>English</name>
          </department>
        </class>
      </score>
    </schedule>
    <schedule date="2017-01-30">
      <score id="2">
        <class id="316" status="-2">
          <name>316c</name>
          <people>87</people>
          <department id="302f">
            <name>English</name>
          </department>
        </class>
      </score>
    </schedule>
  </scheduleList>
</result>
以下是我尝试执行的循环:

    url <- "XXXXXXXXXXX"
        session <-html_session(url)
        form  <-html_form(read_html(url))[[1]]
        for (i in 1:2){
          d=c("S1","S2")
          filled_form[i] <- set_values(form,
                                       "id" = d[i],
                                       "start" = "2017-01-17",
                                       "end" = "2017-02-03",
                                       "Password" = "lll")
          s[i] <- submit_form(session,filled_form[i])
        }

    Error in filled_form[i] <- set_values(form, id = d[i],  : 
      object 'filled_form' not found

url在代码中存储值之前,需要在代码中填充对象
s
。它们存在于原始代码中,但不在循环中

url <- "XXXXXXXXXXX"
session <-html_session(url)
form  <-html_form(read_html(url))[[1]]
filled_form <- list()
s <- list()
for (i in 1:2){
  d=c("S1","S2")
  filled_form[[i]] <- set_values(form,
                               "id" = d[i],
                               "start" = "2017-01-17",
                               "end" = "2017-02-03",
                               "Password" = "lll")
  s[[i]] <- submit_form(session,filled_form[i])
}

url在代码中存储值之前,需要在代码中填充对象
s
。它们存在于原始代码中,但不在循环中

url <- "XXXXXXXXXXX"
session <-html_session(url)
form  <-html_form(read_html(url))[[1]]
filled_form <- list()
s <- list()
for (i in 1:2){
  d=c("S1","S2")
  filled_form[[i]] <- set_values(form,
                               "id" = d[i],
                               "start" = "2017-01-17",
                               "end" = "2017-02-03",
                               "Password" = "lll")
  s[[i]] <- submit_form(session,filled_form[i])
}

url您还可以通过创建一个用户定义的函数并通过
lappy
函数传递一个
ids
列表来优化它。它不起作用,它说错误:找不到可能的提交目标。此外:警告消息:在填充表单[i]中,我更新了上面的答案,尝试使用返回列表周围的双括号进行循环。试试看它是否有用。是的,它有效!惊人:)为什么它是双循环?顺便问一下,我是否也需要将下面的代码放入循环中?因为如果我想执行read_xml函数,还有两个要做,比如s[[1]]$response和s[[2]]$response。谢谢!然后,
z[[i]]您还可以通过创建一个用户定义的函数并通过
lappy
函数传递一个
ids
列表来优化它。它不起作用,它说错误:找不到可能的提交目标。此外:警告消息:在填充表单[i]中,我更新了上面的答案,尝试使用返回列表周围的双括号进行循环。试试看它是否有用。是的,它有效!惊人:)为什么它是双循环?顺便问一下,我是否也需要将下面的代码放入循环中?因为如果我想执行read_xml函数,还有两个要做,比如s[[1]]$response和s[[2]]$response。谢谢!然后
z[[i]]您是否能够共享url,因为可能有一些方法可以使用xml更优化地提取相关数据tools@user20650你好对不起,我无法提供url。另外,您需要购买一个帐户才能登录。xml格式的网站看起来与我上面提供的完全相同,但S1在课堂上有2个日期,S2在课堂上有5个日期,长度略有不同。@user20650刚刚上传了我上面的无效代码。您是否可以共享url,因为可能有更优的方法使用xml提取相关数据tools@user20650你好对不起,我无法提供url。另外,您需要购买一个帐户才能登录。xml格式的网站看起来与我上面提供的完全相同,但S1在类中有2个日期,S2在类中有5个日期,长度略有不同。@user20650刚刚上传了我上面的无效代码
url <- "XXXXXXXXXXX"
session <-html_session(url)
form  <-html_form(read_html(url))[[1]]
filled_form <- list()
s <- list()
for (i in 1:2){
  d=c("S1","S2")
  filled_form[[i]] <- set_values(form,
                               "id" = d[i],
                               "start" = "2017-01-17",
                               "end" = "2017-02-03",
                               "Password" = "lll")
  s[[i]] <- submit_form(session,filled_form[i])
}