创建一个rvest :: html_session给servr :: httd http服务器

时间:2018-02-07 22:56:41

标签: r session rvest servr

我正在开发一个需要访问网页的项目,我这样做 rvest::html_session()。有关文档和培训,我想设置 一个可重复的例子并考虑了以下内容。

  1. 使用servr::httd(system.file("egwebsite", package = "<pkgname>"), daemon = TRUE, browser = FALSE)设置简单的HTTP服务器

  2. 使用rvest::html_session("http://127.0.0.1:4321")设置html 会话。

  3. 但是,以下简单示例在Linux上的表现不同(Debian 9) 和Windows 10.(我没有轻松访问OSx并且没有测试过 OS)。

    # On Windows
    servr::httd(daemon = TRUE, browser = FALSE, port = 4321) 
    ## Serving the directory /home/dewittpe/so/my-servr-question at http://127.0.0.1:4321
    ## To stop the server, run servr::daemon_stop("94019719908480") or restart your R session
    
    R.utils::withTimeout(
                        {
                          s <- rvest::html_session("http://127.0.0.1:4321")
                        },
                        timeout = 3,
                        onTimeout = "error") 
    
    s 
    ## <session> http://127.0.0.1:4321/
    ##   Status: 200
    ##   Type:   text/html
    ##   Size:   2352
    servr::daemon_stop()
    

    但是,在我的Linux机器上(Debian 9),我得到以下内容

    servr::httd(daemon = TRUE, browser = FALSE, port = 4321) 
    ## Serving the directory /home/dewittpe/so/my-servr-question at http://127.0.0.1:4321
    ## To stop the server, run servr::daemon_stop("94019719908480") or restart your R session
    
    R.utils::withTimeout(
                        {
                          s <- rvest::html_session("http://127.0.0.1:4321")
                        },
                        timeout = 3,
                        onTimeout = "error") 
    ## Error: reached elapsed time limit
    ## Error in curl::curl_fetch_memory(url, handle = handle) :
    ##   Operation was aborted by an application callback
    

    也就是说,我无法在同一个R互动中创建html_session 生成http服务器的会话。但是,如果我开始第二个R. 会话在离开初始会话时,我能够创建 html_session没有错误。

    我可以做什么,以便根据html_session创建servr::httd Linux上同一R会话中的HTTP服务器?

    修改1

    如果我将httr::verbose()添加到html_session来电,我会在成功创建会话时获得以下内容。当进程挂起并且无法创建会话时,输出会在最后->处停止,并且不会显示包含<-的所有行。

    > s <- html_session("http://127.0.0.1:4321", httr::verbose())
    -> GET / HTTP/1.1
    -> Host: 127.0.0.1:4321
    -> User-Agent: libcurl/7.52.1 r-curl/3.1 httr/1.3.1
    -> Accept-Encoding: gzip, deflate
    -> Accept: application/json, text/xml, application/xml, */*
    ->
    <- HTTP/1.1 200 OK
    <- Content-Type: text/html
    <- Content-Length: 61303
    <-
    

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法,在子流程中运行servr::httd。此解决方案需要subprocess包。

首先,辅助函数R_binary将在Windows或基于unix的操作系统上返回R二进制文件的文件路径。

R_binary <- function () {
  R_exe <- ifelse (tolower(.Platform$OS.type) == "windows", "R.exe", "R")
  return(file.path(R.home("bin"), R_exe))
}

接下来,启动R vanilla作为子流程。

subR <- subprocess::spawn_process(R_binary(), c("--vanilla"))

然后在子流程

中启动HTTP服务器
subprocess::process_write(subR, 'servr::httd(".", browser = FALSE, port = 4321)\n')
## [1] 47
subprocess::process_read(subR)$stderr
## [1] "Serving the directory /home/dewittpe/so/my-servr-question at http://127.0.0.1:4321"

快速测试,显示活动R会话和HTTP服务器之间存在通信:

session <- rvest::html_session("http://127.0.0.1:4321")
session
## <session> http://127.0.0.1:4321/
##   Status: 200
##   Type:   text/html
##   Size:   1054

最后,杀死子流程

subprocess::process_kill(subR)