自动化终端行命令的最佳方法? Mac / get_iPlayer

时间:2021-07-12 11:01:19

标签: python r terminal automation command-line-interface

我正在寻找有关如何使用 Mac 通过终端自动执行命令的建议。

我正在使用一个名为 get_iPlayer 的 CLI 程序,它基本上允许您在本地下载和存储 BBC iPlayer 内容。这实际上并不是我使用它的原因。我正在收集有关其目录的数据(用于学术研究目的,而不是商业用途),并且为此非常有用。它缓存了目录中所有程序的大量数据,但不是所有可用数据。

要获取其他数据,您必须通过终端中的命令指定特定程序,然后该命令将下载一个包含相关元数据的小型 xml 文件。命令如下所示:

get_iplayer --type=tv --pid<insert unique programme code here> --metadata-only

我在一个 csv 文件中列出了所有唯一程序代码(它们称为 pid),我想知道是否可以自动执行此过程。 IE。编写一个脚本来运行该行,但每次都使用不同的 pid

有几个警告值得一提:

  1. 我真的只有使用 R 的经验。我怀疑 Python 会更好,如果这是唯一的选择,那就足够公平了!
  2. 其中有 129,000 个要查找,因此如果可以自动执行此过程,我需要编写一个脚本,在每个新查询之间添加延迟,以免杀死 BBC 服务器!

任何有关如何解决此问题的建议都将受到欢迎。我对编程的了解非常有限,如果这是一个非常明显的问题,请见谅!

1 个答案:

答案 0 :(得分:1)

R 的 systemsystem2 可以很好地调用外部程序,但我个人更喜欢 processx 包,因为它可以更好地处理参数。我的猜测是你可以做这样的事情(未经验证,我没有那个 cli 工具):

pids <- c('111', '222', '333')
out <- lapply(sprintf("get_iplayer --type=tv --pid%s --metadata-only", pids),
             function(pid) { Sys.sleep(3); system(pid, intern = TRUE); })

这在每个命令之前使用 3 秒睡眠,根据您自己的喜好进行调整。我不知道这是否符合他们的使用条款,也不知道他们是否会为您限制连接。如果命令开始失败或您需要中断它,以保留所有已检索数据的方式执行此操作可能会更健壮:

out <- list()
errcount <- 0
for (pid in pids) {
  out[[pid]] <- tryCatch({
    system(sprintf("get_iplayer --type=tv --pid%s --metadata-only", pid),
           intern = TRUE)
  }, error = function(e) e)
  if (inherits(out[[pid]], "error")) {
    errcount <- errcount + 1
    if (errcount > 3) {
      warning("errcount over 3, stopping", call. = FALSE)
      break
    }
  }
}

如果命令返回非 0 退出状态(0 通常表示正常操作),则 R 将发出警告并继续。如果出现严重问题,它会发出错误 (stop),但无论如何都要尝试继续。我添加了 errcount 步骤以对重复失败更加稳健:如果它重复发生(3 可能不是您容忍度的正确数字),您可能不想继续前进,尤其是因为您处理其中的 129K。

R 在这方面没有其他语言的优势。

相关问题