Невозможно очистить несколько страниц с помощью phantomjs в r

Я пытаюсь собрать данные оценщика округа по историческим значениям свойств для нескольких участков, сгенерированных с помощью javascript из https://www.washoecounty.us/assessor/cama/?command=assessment_data&parid=07101001 с использованием фантомов, контролируемых RSelenium. 'paraid' в URL - это 9-значный номер посылки. У меня есть фрейм данных, содержащий список номеров посылок, которые меня интересуют (всего несколько сотен), но я пытался заставить код работать на небольшом подмножестве из них:

parcel_nums
[1] "00905101" "00905102" "00905103" "00905104" "00905105" 
[6] "00905106" "00905107" "00905108" "00905201" "00905202"

Мне нужно очистить данные в таблице, сгенерированной на странице для каждой посылки, и сохранить ее. Я решил записать страницу в файл "output.htm", а затем проанализировать файл. Мой код выглядит следующим образом:

require(plyr)
require(rvest)
require(RSelenium)
require(tidyr)
require(dplyr)

parcel_nums <- prop_attr$APN[1:10]  #Vector of parcel numbers
pJS <- phantom()
remDr <- remoteDriver(browserName = "phantomjs")
remDr$open()

result <- remDr$phantomExecute("var page = this;
                            var fs = require(\"fs\");
                            page.onLoadFinished = function(status) {
                            var file = fs.open(\"output.htm\", \"w\");
                            file.write(page.content);
                            file.close();
                            };")

for (i in 1:length(parcel_nums)){
    url <- paste("https://www.washoecounty.us/assessor/cama/?command=assessment_data&parid=", 
        parcel_nums[i], sep = "")
    Sys.sleep(5)

    emDr$navigate(url)

    dat <- read_html("output.htm", encoding = "UTF-8") %>% 
        html_nodes("table") %>% 
        html_table(, header = T)
    df <- data.frame(dat)

    #assign parcel number to panel
    df$apn <- parcel_nums[i]
    #on first iteratation initialize final data frame, on sebsequent iterations append the final data frame
    ifelse(i == 1, parcel_data <- df, parcel_data <- rbind(parcel_data, df))
}
remDr$close
pJS$stop()

Это будет отлично работать для одной или двух итераций цикла, но внезапно прекратит сохранять данные, сгенерированные JavaScript, и выдаст ошибку:

 Error in `$<-.data.frame`(`*tmp*`, "apn", value = "00905105") : 
 replacement has 1 row, data has 0 

что связано с тем, что синтаксический анализатор не находит таблицу в выходном файле, потому что она не сохраняется. Я не уверен, есть ли проблема с выбранной реализацией или есть какая-то особенность конкретного сайта, который вызывает проблему. Я не знаком с JavaScript, поэтому используемый фрагмент кода взят из примера, который я нашел. Спасибо за любую помощь.

Приведенный ниже ответ работал отлично. Я также переместил Sys.sleep(5) после $navigate, чтобы дать странице время для загрузки JavaScript. Цикл теперь выполняется до конца.

2 ответа

Решение
require(plyr)
require(rvest)
require(RSelenium)
require(tidyr)
require(dplyr)

parcel_nums <- prop_attr$APN[1:10]  #Vector of parcel numbers
#pJS <- phantom()
remDr <- remoteDriver()
remDr$open()

# #result <- remDr$executeScript("var page = this;
#                                var fs = require(\"fs\");
#                                page.onLoadFinished = function(status) {
#                                var file = fs.open(\"output.htm\", \"w\");
#                                file.write(page.content);
#                                file.close();
#                                };")
#length(parcel_nums)
for (i in 1:length(parcel_nums)){
  url <- paste("https://www.washoecounty.us/assessor/cama/?command=assessment_data&parid=", 
               parcel_nums[i], sep = "")
  Sys.sleep(5)

  remDr$navigate(url)
  doc <- htmlParse(remDr$getPageSource()[[1]])
  doc_t<-readHTMLTable(doc,header = TRUE)$`NULL`
  df<-data.frame(doc_t)

  #assign parcel number to panel
  df$apn <- parcel_nums[i]
  #on first iteratation initialize final data frame, on sebsequent iterations append the final data frame
  ifelse(i == 1, parcel_data <- df, parcel_data <- rbind(parcel_data, df))
}
remDr$close

Это дало мне решение. И это должно работать с фантомом тоже. Я прошу вас проверить и ответить.

Я потерял целый день, пытаясь решить аналогичную проблему. Поэтому я делюсь своими знаниями, чтобы помочь другим сэкономить время и нервы..

Я предполагаю, что мы должны понимать, что открытие, навигация и другие действия по просмотру через удаленный драйвер требуют времени для завершения. Поэтому нам нужно подождать, прежде чем мы попытаемся прочитать или сделать что-нибудь на страницах, которые мы ожидаем очистить.

Мои проблемы были решены, когда я представил Sys.sleep(5) после remDr$navigate(url) вызов.

Кажется, что более аккуратное решение состоит из вставки remDr$setTimeout(type = "page load", milliseconds = 10000) как предложено, как проверить, закончилась ли загрузка страницы в RSelenium, но еще не проверял.

Другие вопросы по тегам