【问题标题】:How to determine if you have an internet connection in R如何确定您是否在 R 中有 Internet 连接
【发布时间】:2020-06-19 06:23:07
【问题描述】:

有时我需要从互联网上下载数据。有时这会失败,因为网站已关闭或因为我的计算机失去了互联网连接。

问题:R 中是否有一些函数会返回 TRUE/FALSE 来判断我是否已连接到互联网?

【问题讨论】:

  • 什么操作系统?在 Windows 中,我认为您必须从 shell 运行 ipconfig,而在 Linux 上则为 ifconfig。然后,您必须解析输出并进行测试。
  • 从远程机器下载数据的能力取决于很多因素,这些因素超出了您的代码的控制范围,并且其状态随时可能发生变化。知道您是否可以下载文件的唯一 100% 确定的方法是尝试下载它并成功。即使您可以开始传输,也不能保证网络连接不会中途中断,因此您无论如何都需要编写代码来应对这种情况。因此,只需编写该代码,并放弃尝试事先检测您是否会成功。
  • 一种更优雅的方法是通过utils::nsl(仅限unix)或curl::nslookup(跨平台)测试dns。

标签: r


【解决方案1】:

curl 包有一个函数has_internet,它通过执行nslookup 进行测试:

curl::has_internet
## function(){
##    !is.null(nslookup("google.com", error = FALSE))
## }

测试 DNS 比检索 URL 更快并且可能更可靠,因为后者可能由于不相关的原因(例如防火墙、服务器关闭等)而失败。

【讨论】:

    【解决方案2】:

    使用RCurl::getURL 函数是一种肮脏的工作。

    if (is.character(getURL("www.google.com"))) {
        out <- TRUE
    } else {
        out <- FALSE
    }
    

    【讨论】:

    • 可以简写为:out &lt;- is.character(getURL("www.google.com"))
    • 感谢您改进我破烂的解决方案。
    • 其实在没有网络getURL报错的时候,应该使用out &lt;-try(is.character(getURL("www.google.com"))) == TRUE
    • 在下面查看我的答案,在 curl 包中找到更优雅的解决方案。
    • 另一种选择:out&lt;-RCurl::url.exists("https://www.google.com") 仅当互联网可用时才适用
    【解决方案3】:

    按照 Spacedman 的建议,尝试解析 ipconfig/ifconfig 的输出。

    havingIP <- function() {
      if (.Platform$OS.type == "windows") {
        ipmessage <- system("ipconfig", intern = TRUE)
      } else {
        ipmessage <- system("ifconfig", intern = TRUE)
      }
      validIP <- "((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
      any(grep(validIP, ipmessage))
    }
    

    带有简单的 TRUE/FALSE 输出

    > havingIP()
    [1] TRUE
    

    【讨论】:

    • 如果接口未启动,我认为 i[pf]config 不会返回有用的返回值? ifconfig 手册页中没有提到它,我不想关闭我的盒子的网络进行测试,因为我正在远程登录,我可能会终止我的连接:)
    • 如果系统的返回值不包含有效的 IP,则函数返回 FALSE。因此,f.e.x.现在在家使用 Linux 我得到了 FALSE,因为我需要成为 root 才能使用 ifconfig。我得到“sh:ifconfig:未找到”在 FALSE 返回值之前回显到 R 终端。
    • 至少在我的电脑上(Mint 基于 linux 3.13),没有网络连接时可以返回 TRUE。
    • 这不会检查您是否有活动的互联网连接。它会检查您是否拥有有效的 IP 地址。我刚刚关闭了我的 wifi,这仍然返回 TRUE。
    • AFAI 正确理解这一点,ifconfig 无论连接如何都会返回有用信息(字符串)(在 macbook osx 10.14 上)
    【解决方案4】:

    受@romans 回答的启发,只是另一个添加到锅中,这仅适用于我认为的 Windows,不确定其他平台:

    canPingSite <- function(test.site) {
        !as.logical(system(paste("ping", test.site)))
    }
    

    我们测试如下:

    > t1 <- canPingSite("www.yahoo.com")
    [...]
    
    > t2 <- canPingSite(";lkjsdflakjdlfhasdfhsad;fs;adjfsdlk")
    [...]
    
    > t1; t2
    [1] TRUE
    [1] FALSE
    

    【讨论】:

    • 我为此获得了两次反对票,但我不知道为什么?我不关心声誉点(它们对我来说毫无意义),但我想了解这个解决方案有什么不好的地方。我投反对票的原因是因为这个解决方案只能在 Windows 上工作,我想这有点公平:)
    • 像这个,在Linux上只适应:canPingSite &lt;- function(test.site) { !as.logical(system(paste("ping -c 1", test.site))) }
    • 我建议添加ping -n 1,因为我们不需要执行标准的 4 次 ping。我没有足够的耐心等待 4 个单独的回复;)
    【解决方案5】:

    只需两行代码即可:

    install.packages('pingr')
    pingr::is_online()
    

    【讨论】:

    • 事实上,你不需要第 2 行。
    • 不客气。 :: 运算符负责处理。
    • 干杯。我知道它逃脱了你:)
    【解决方案6】:

    Bioconductor 的 Biobase 包具有测试互联网连接的功能。

    Biobase::testBioCConnection()
    

    下面是这个函数的一个经过大量修改的版本,用于测试从 URL 读取行的能力。

    can_internet <- function(url = "http://www.google.com") {
    
        # test the http capabilities of the current R build
        if (!capabilities(what = "http/ftp")) return(FALSE)
    
        # test connection by trying to read first line of url
        test <- try(suppressWarnings(readLines(url, n = 1)), silent = TRUE)
    
        # return FALSE if test inherits 'try-error' class
        !inherits(test, "try-error")
    }
    
    can_internet()
    

    【讨论】:

      【解决方案7】:

      所有这些答案都使用基础 R 之外的包或代码。以下是仅使用基础 R 的方法:

      # IANA's test website
      is_online <- function(site="http://example.com/") {
        tryCatch({
          readLines(site,n=1)
          TRUE
        },
        warning = function(w) invokeRestart("muffleWarning"),
        error = function(e) FALSE)
      }
      

      【讨论】:

        【解决方案8】:

        上面的函数来自eyjo

        havingIP <- function() {
         if (.Platform$OS.type == "windows") {
           ipmessage <- system("ipconfig", intern = TRUE)
         } else {
           ipmessage <- system("ifconfig", intern = TRUE)
         }
         validIP <- "((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
         any(grep(validIP, ipmessage))
        }
        

        还为 localhost ip "127.0.0.1" 返回 true,需要将其删除以防止误报。例如下图:

         havingIP <- function() {
         if (.Platform$OS.type == "windows") {
           ipmessage <- system("ipconfig", intern = TRUE)
         } else {
           ipmessage <- system("ifconfig", intern = TRUE)
         }
         validIP <- "((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
         any(grep(validIP, ipmessage[-grep("127.0.0.1", ipmessage)]))
        }
        

        但更好的解决方案是通过修改 validIP 的正则表达式来阻止本地主机。

        【讨论】:

        • 最后一个对我不起作用;现在即使我有互联网,它也显示为 FALSE。
        【解决方案9】:

        这是 eyjo 答案的一个版本,它为了速度而牺牲了准确性。

        IPavailable <- function() {
          cmd <- switch(.Platform$OS.type, "windows" = "ipconfig", "ifconfig")
          any(grep("(\\d+(\\.|$)){4}", system(cmd, intern = TRUE)))
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-03-31
          • 2012-02-12
          • 2011-11-29
          • 1970-01-01
          • 2017-05-05
          • 2011-03-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多