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

Best way to automate terminal line commands? Mac / get_iPlayer

我正在寻找一些关于如何使用 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 服务器!

我们非常欢迎任何有关如何处理此问题的建议。我对编程的了解非常有限,如果这是一个非常明显的问题,我深表歉意!

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
    }
  }
}

如果命令returns非0退出状态(0一般表示正常运行),那么R会发出警告并继续。如果出现严重错误,它会发出错误 (stop),但无论如何都要尝试继续。我添加了 errcount 步骤以更稳健地应对重复失败:如果它反复发生(3 可能不适合您的容忍度),您可能不想继续前进,尤其是因为您处理其中的 129K。

R 在这方面与其他语言相比没有优势。