RSelenium:抓取动态加载的页面,加载缓慢

时间:2017-03-04 11:10:05

标签: r selenium selenium-chromedriver rvest rselenium

我不确定是不是因为我的互联网速度很慢,但是当我向下滚动页面时,我正试图抓取一个加载信息的网站。我正在执行一个到达页面末尾的脚本,并等待Selenium / Chrome服务器加载其他内容。服务器会更新并加载新内容,因为我能够抓取最初不在页面上的信息,并且新内容显示在chrome查看器上,但它只更新一次。我将Sys.sleep()函数设置为每次等待一分钟,以便内容有足够的时间加载,但它仍然不会更新多次。我错误地使用RSelenium吗?是否有其他方法可以抓取动态加载的网站?

无论如何,您提供的任何建议或帮助都会很棒。

以下是我认为我的代码在页面末尾加载新内容的相关部分:

for(i in 1:3){
  webElem <- remDr$findElement('css', 'body')
  remDr$executeScript('window.scrollTo(0, document.body.scrollHeight);') 
  Sys.sleep(60)
}

以下是完整代码:

library(RSelenium)
library(rvest)
library(stringr)

rsDriver(port = 4444L, browser = 'chrome')
remDr <- remoteDriver(browser = 'chrome')
remDr$open()
remDr$navigate('http://www.codewars.com/kata')

#find the total number of recorded katas
tot_kata <- remDr$findElement(using = 'css', '.is-gray-text')$getElementText() %>%
  unlist() %>%
  str_extract('\\d+') %>%
  as.numeric()

#there are about 30 katas per page reload
tot_pages <- (tot_kata/30) %>%
  ceiling()

#will be 1:tot_pages once I know the below code works
for(i in 1:3){
  webElem <- remDr$findElement('css', 'body')
  remDr$executeScript('window.scrollTo(0, document.body.scrollHeight);') 
  Sys.sleep(60)
}

page_source <- remDr$getPageSource()

kata_vector <- read_html(page_source[[1]]) %>%
  html_nodes('.item-title a') %>%
  html_attr('href') %>%
  str_replace('/kata/', '')

remDr$close

1 个答案:

答案 0 :(得分:1)

该网站提供api,它应该是第一个停靠点。如果不这样做,您可以使用例如:

访问各个页面
http://www.codewars.com/kata?page=21

如果您想要滚动到页面底部,直到RSelenium没有更多内容,您可以使用“正在加载...”元素,它有一个class=js-infinite-marker。虽然我们仍然在页面上有这个元素,但我们每秒都会尝试向下滚动它(对于任何问题都有一些错误)。如果元素不存在,我们假设所有内容都已加载:

library(RSelenium)

rD <- rsDriver(port = 4444L, browser = 'chrome')
remDr <- rD$client # You dont need to use the open method 
remDr$navigate('http://www.codewars.com/kata')
chk <- FALSE
while(!chk){
  webElem <- remDr$findElements("css", ".js-infinite-marker")
  if(length(webElem) > 0L){
    tryCatch(
      remDr$executeScript("elem = arguments[0]; 
                      elem.scrollIntoView(); 
                        return true;", list(webElem[[1]])), 
      error = function(e){}
    )
    Sys.sleep(1L)
  }else{
    chk <- TRUE
  }
}