R在https站点上抓取表

R在https站点上抓取表,r,R,我正在尝试使用带有附加代码的RCurl包从以下网站“”中刮取报告日志表。它从页面中提取元素,但当我滚动浏览存储在“page”下的列表中的10个项目时,没有一个元素包含表 library("RCurl") # Read page page <- GET( url="https://heritageunits.com/Locomotive/Detail/NS8098", config(cainfo = cafile), ssl.verifyhost = FALSE ) 库(“RCur

我正在尝试使用带有附加代码的RCurl包从以下网站“”中刮取报告日志表。它从页面中提取元素,但当我滚动浏览存储在“page”下的列表中的10个项目时,没有一个元素包含表

library("RCurl")
# Read page
page <- GET(
  url="https://heritageunits.com/Locomotive/Detail/NS8098",
  config(cainfo = cafile), ssl.verifyhost = FALSE
)
库(“RCurl”)
#阅读页面

page有时我可以在源代码中找到一个json文件,您可以直接使用它,但我找不到。我使用了RSelenium,让它点击下一步按钮,然后循环浏览。这种方法很脆弱,所以在运行时必须注意。如果datatable没有完全加载,它将复制最后一页,因此我使用了一个小Sys.sleep来确保它等待的时间足够长。我建议在末尾检查重复的行,以捕捉这一点。同样,它是脆弱的,但它的工作

library(RSelenium)
library(XML)
library(foreach)


# Start Selenium server
checkForServer()
startServer()

remDr <- 
  remoteDriver(
    remoteServerAddr = "localhost" 
    , port = 4444
    , browserName = "chrome"
)

remDr$open()

# Navigate to page
remDr$navigate("https://www.heritageunits.com/Locomotive/Detail/NS8098")

# Snag the html
outhtml <- remDr$findElement(using = 'xpath', "//*")
out<-outhtml$getElementAttribute("outerHTML")[[1]]

# Parse with RCurl
doc<-htmlParse(out, encoding = "UTF-8")

# get the last page so we can cycle through
PageNodes <- getNodeSet(doc, '//*[(@id = "history_paginate")]')
Pages <- sapply(X = PageNodes, FUN = xmlValue)
LastPage = as.numeric(gsub('Previous12345\\…(.*)Next', '\\1',Pages))


# loop through one click at a time
Locomotive <- foreach(i = 1:(LastPage-1), .combine = 'rbind', .verbose = TRUE) %do% {

  if(i == 1){

    readHTMLTable(doc)$history

  } else {

    nextpage <- remDr$findElement("css selector", '#history_next')
    nextpage$sendKeysToElement(list(key ="enter"))

    # Take it slow so it gets each page
    Sys.sleep(.50)

    outhtml <- remDr$findElement(using = 'xpath', "//*")
    out<-outhtml$getElementAttribute("outerHTML")[[1]]

    # Parse with RCurl
    doc<-htmlParse(out, encoding = "UTF-8")
    readHTMLTable(doc)$history
  }


}
库(RSelenium)
库(XML)
图书馆(foreach)
#启动Selenium服务器
checkForServer()
startServer()

remDr错过了几分钟。我取了硒元素片段,并根据需要进行了修改。不过我觉得这个短一点。我没有遇到任何页面未加载的问题

## required packages
library(RSelenium)
library(rvest)
library(magrittr)
library(dplyr)


## start RSelenium
checkForServer()
startServer()
remDr <- remoteDriver()
remDr$open()

## send Selenium to the page
remDr$navigate("https://www.heritageunits.com/Locomotive/Detail/NS8098")

## get the page html
page_source <- remDr$getPageSource()

## parse it and extract the table, convert to data.frame
read_html(page_source[[1]]) %>% html_nodes("table") %>% html_table() %>% extract2(1)
##必需的软件包
图书馆(资源库)
图书馆(rvest)
图书馆(magrittr)
图书馆(dplyr)
##起始硒
checkForServer()
startServer()
remDr%html_table()%%>%extract2(1)

在JackStat上面概述的基础上,我对页面确定方案进行了修改,以拾取少于5页的单元(JackStat的算法将抛出错误)。我还为它设置了一个导入,以提取要跟踪的感兴趣的单元。为使其在Windows PC上运行的步骤添加了注释

library(RSelenium)
library(XML)
library(foreach)

### Insure that the selenium-server-standalone.jar file and the Google Chrome driver are in the same folder
### as the Windows command directory setting
### Open Windows command
### Type in "java -jar selenium-server-standalone.jar" and hit enter

setwd("H:/heritage_units")
hu <- read.table("hu_tracked_101316.csv", sep = ",", header = TRUE, colClasses = "character")
hu.c <- hu[, 1]

# Start Selenium server
checkForServer()
startServer()

remDr <- 
    remoteDriver(
            remoteServerAddr = "localhost" 
            , port = 4444
            , browserName = "chrome"
    )

remDr$open()

master <- data.frame('Spotted On'=factor(), 'Location'=factor(), 'Directon'=factor(), 'Train No'=factor(), 'Leading'=factor(), 'Spotter Reputation'=factor(), 'Heritage Unit'=character()) 

for (u in seq_along(hu.c)) {
    url <- paste("https://www.heritageunits.com/Locomotive/Detail/", hu.c[u], sep="")
    print(hu.c[u])

    # Navigate to page
    remDr$navigate(url)

    # Snag the html
    outhtml <- remDr$findElement(using = 'xpath', "//*")
    out<-outhtml$getElementAttribute("outerHTML")[[1]]

    # Parse with RCurl
    doc<-htmlParse(out, encoding = "UTF-8")

    # get the last page so we can cycle through
    PageNodes <- getNodeSet(doc, '//*[(@id = "history_paginate")]')
    Pages <- sapply(X = PageNodes, FUN = xmlValue)
    # Find horizontal ellipsis in page information
    sc <- 0
    for (j in 1:nchar(Pages)){
            if (!(grepl("[[:alpha:]]", substr(Pages, j, j)) | grepl("[[:digit:]]", substr(Pages, j, j)))){
                    sc <- j
            }
    }
    if (sc==0) {
            posN <- gregexpr(pattern ='N', Pages)
            LastPage <- substr(Pages, posN[[1]]-1, posN[[1]]-1)
    }else{
            posN <- gregexpr(pattern ='N', Pages)
            LastPage <- substr(Pages, sc+1, posN[[1]]-1)
    }

    temp1 <- readHTMLTable(doc)$history
    temp1$'Heritage Unit' <- hu.c[u]
    for (i in 2:LastPage){
            nextpage <- remDr$findElement("css selector", '#history_next')
            nextpage$sendKeysToElement(list(key ="enter"))

            # Take it slow so it gets each page
            Sys.sleep(.50)

            outhtml <- remDr$findElement(using = 'xpath', "//*")
            out<-outhtml$getElementAttribute("outerHTML")[[1]]

            # Parse with RCurl
            doc<-htmlParse(out, encoding = "UTF-8")
            temp2 <- readHTMLTable(doc)$history
            temp2$'Heritage Unit' <- hu.c[u]
            temp1 <- rbind(temp1, temp2)
    }
    master <- rbind(master, temp1)
}

write.csv(master, "hu_sel_date.csv")
库(RSelenium)
库(XML)
图书馆(foreach)
###确保selenium-server-standalone.jar文件和Google Chrome驱动程序位于同一文件夹中
###作为Windows命令目录设置
###打开窗口命令
###键入“java-jar selenium server standalone.jar”并按enter键
setwd(“H:/U单位”)

太好了!我写了一个循环来获取其他页面。您还应该添加
read\u html(page\u source[[1]])%%>%html\u节点(“表”)%%>%html\u table()%%>%.[1]
Cool。我只是指
rvest
处理的位。我不确定
rvest
能否完成下一页的内容,因此您的解决方案在这方面会更好。谢谢@Jonathan Carroll。非常感谢。与上面的评论类似,我在remDr$open()代码行中遇到一个错误,不确定是什么原因导致它在此时停止。开始一个新问题或使用一些Google fu。祝你好运。@JonathanCarroll:谢谢-见上面的评论,仍然不起作用,但我正在尝试其他事情。你是在Mac上偶然做的吗?这里有一个JSON源代码:
https://heritageunits.com/Locomotive/DetailHistory
但该网站还使用javascript填充动态计算的额外表单字段。RSelenium是使用这个方法的唯一方法,除非你想找到一种方法来提取js执行内容并将其传递到V8中,但即使这样,它似乎也依赖于DOM的存在,所以prbly无法工作。谢谢@JackStat。非常感谢。我运行了此代码并得到一个错误:错误:摘要:未知错误详细信息:处理命令时发生未知服务器端错误。类:代码中remDr$open()行的java.lang.IllegalStateException。我认为这可能与我的旧笔记本电脑Windows 7 enterprise有关,在Windows 10桌面上试用了它,在相同的代码位置得到了:queryRD中的错误(paste0(serverURL,“/session”),“POST”,qdata=toJSON(serverOpts))。有什么想法吗?试试空的遥控器
remDr@JackStat:谢谢。还是不行。我正在调查Windows驱动程序、Java接口/版本和R Selenium。问题似乎在于这三者之间的联系。碰巧,你是在Mac电脑上做的吗?@JackStat我在过去几个月里一直在使用它,并最终在Windows PC上使用它。给未来的读者留下一条评论:这是一个非常好的例子,说明在哪里绝对需要RSelenium。请参阅我对JackStat答案的评论,了解原因。这里有一个很好的实用示例。话虽如此,该站点有一个API(在他们的服务文档中)。你应该与他们联系,看看你是否可以用
httr
vs来点击API来完成所有这些刮取。刮取比API调用更脆弱。