代码之家  ›  专栏  ›  技术社区  ›  Peter

创建到servr::httd http服务器的rvest::html\u会话

  •  0
  • Peter  · 技术社区  · 8 年前

    我正在从事一个需要访问网页的项目,我通过 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 一场

    但是,以下简单示例在Linux上的行为不同(Debian 9) 和Windows 10。(我无法轻松访问OSx,也没有在 该操作系统)。

    # 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
    

    也就是说,我无法创建 html_session 在同一R interactive中 生成http服务器的会话。但是,如果我启动第二个R 会话在保持初始会话运行的同时,我可以创建 这个 html\U会话 没有错误。

    如何创建 html\U会话 基于 servr::httd Linux上相同R会话中的HTTP服务器?

    编辑1

    如果我添加 httr::verbose() html\U会话 成功创建会话后,调用我获取以下信息。当进程挂起且无法创建会话时,输出将在最后一个 -> 没有一行 <- 如图所示。

    > 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 回复  |  直到 8 年前
        1
  •  0
  •   Peter    8 年前

    我找到了问题的解决方案,快跑 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)
    
    推荐文章