Соскреб в сети с R и phantomjs с помощью небольшого js-скрипта, возвращающего ошибку - PullRequest
0 голосов
/ 07 октября 2018

Мне нужно получить содержимое этой страницы, содержащее несколько сценариев: https://grouper.swissdrg.org/swissdrg/single?version=7.3&pc=1337_70_0_0_M_11_00_15_0_2018/08/07_2018/08/22_C18.4_C07_-_45.81.11$$&provider=acute&locale=de. Для других страниц, содержащих js, работает нормально, но не для того, который мне нужен.

phantomjs.exe находится в корневом каталоге и успешно вызывается системным вызовом (64-разрядная версия win7):

system ("phantomjs WebScrapeV1.js")

JavaФайл сценария WebScrapeV1.js выглядит следующим образом:

var url ='https://grouper.swissdrg.org/swissdrg/single?version=7.3&pc=1337_70_0_0_M_11_00_15_0_2018/08/07_2018/08/22_C18.4_C07_-_45.81.11$$&provider=acute&locale=de';
var page = new WebPage()
var fs = require('fs');
page.open(url, function (status) {
  just_wait();
});
function just_wait() {
  setTimeout(function() {
    fs.write('WebScrapeV1.html', page.content, 'w');
    phantom.exit();
  }, 2500);
}

Это ошибка, которую я получаю:

Ошибка: [mobx.array] Индекс вне границ, функция (t) {return {ключ: t.version, текст: t ["name _" + e.root.navigation.lang], значение: t.version}} больше 30

https://grouper.swissdrg.org/packs/App-3dd15966701d9f6fd4db.js:1 в бр. Необработанное обещаниеотклонение TypeError: undefined не является конструктором (оценивается как n.push (this.pdx))

1 Ответ

0 голосов
/ 07 октября 2018

Более длительный тайм-аут может быть тем, что вам нужно.Мне пришлось использовать 3600, чтобы получить все содержимое (этот сайт был очень медленным для меня).Вот способ, которым вы можете изменить время ожидания в случае ошибок без необходимости вручную изменять скрипт phantomjs.

Сначала мы сделаем функцию, чтобы обернуть всю сложность:

#' Read contents from a URL with phantomjs
#' 
#' @param url the URL to scrape
#' @param timeout how long to wait, default is `2500` (ms)
#' @param .verbose, if `TRUE` (the default), display the generated 
#'        scraping script and any `stdout` output from phantomjs
read_phantom <- function(url, timeout=2500, .verbose = TRUE) {

  suppressPackageStartupMessages({
    require("glue", character.only = TRUE, quiet=TRUE)
    require("crayon", character.only = TRUE, quiet=TRUE)
  })

  phantom_template <- "
var url = {url};
var page = new WebPage()
var fs = require('fs');
page.open(url, function (status) {{
  just_wait();
});
function just_wait() {{
  setTimeout(function() {{
    fs.write({output_file}, page.content, 'w');
    phantom.exit();
  }, {timeout});
}
" 

  url <- shQuote(url)

  phantom_bin <- Sys.which("phantomjs")

  tf_in <- tempfile(fileext = ".js")
  on.exit(unlink(tf_in), add=TRUE)

  tf_out <- tempfile(fileext = ".html")
  on.exit(unlink(tf_out), add=TRUE)

  output_file <- shQuote(tf_out)

  phantom_script <- glue(phantom_template)

  if (.verbose) {
    cat(
      crayon::white("Using the following generated scraping script:\n"),
      crayon::green(phantom_script), "\n", sep=""
    )
  }

  writeLines(phantom_script, tf_in)

  system2(
    command = phantom_bin, 
    args = tf_in,
    stdout = if (.verbose) "" else NULL
  )

  paste0(readLines(tf_out, warn = FALSE), collapse="\n")

}

Теперь мы будем использовать ваш URL с более длительным тайм-аутом:

read_phantom(
  url = "https://grouper.swissdrg.org/swissdrg/single?version=7.3&pc=1337_70_0_0_M_11_00_15_0_2018/08/07_2018/08/22_C18.4_C07_-_45.81.11$$&provider=acute&locale=de",
  timeout = 3600
) -> doc

substr(doc, 1, 100)
## [1] "<html><head>\n<script src=\"https://js-agent.newrelic.com/nr-1071.min.js\"></script><script type=\" text"

nchar(doc)
## [1] 26858

Обратите внимание, что phantomjs считается устаревшим инструментом, поскольку основные разработчики продвинулись дальше с тех пор, как на сцене появился Chrome без головы.К сожалению, нет никакого способа установить тайм-аут для безглавого Chrome в простом линейном интерфейсе cmd, так что вы сейчас вроде как застряли с фантомами.

Я бы предложил попробовать splashr но вы на Windows и splashr требуется Docker;альтернативно, decapitated имеет аналог оркестровки gepetto, но для этого требуется nodejs;любая из этих комбинаций кажется болезненной для людей, работающих над этой устаревшей операционной системой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...