自动化终端行命令的最佳方式? 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
的脚本。
有几点值得一提:
- 我真的只有使用 R 的经验。我怀疑 python 会更好,如果这是唯一的选择,那就太公平了!
- 其中有 129,000 个要查找,所以如果可以自动执行此过程,我需要编写一个脚本,在每个新查询之间添加延迟,以免杀死 BBC 服务器!
我们非常欢迎任何有关如何处理此问题的建议。我对编程的了解非常有限,如果这是一个非常明显的问题,我深表歉意!
R 的 system
或 system2
可以很好地调用外部程序,尽管我个人更喜欢 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 在这方面与其他语言相比没有优势。
我正在寻找一些关于如何使用 Mac 通过终端自动执行命令的建议。
我正在使用名为 get_iPlayer 的 CLI 程序,它基本上允许您在本地下载和存储 BBC iPlayer 内容。这实际上并不是我使用它的原因。我正在收集有关其目录的数据(用于学术研究目的,而非商业用途),它对此非常有用。它缓存了关于目录中所有程序的一大堆数据,但不是所有可用数据。
要获取其他数据,您必须通过终端中的命令指定特定程序,然后该程序将下载一个包含相关元数据的小 xml 文件。命令如下所示:
get_iplayer --type=tv --pid<insert unique programme code here> --metadata-only
我在一个 csv 文件中列出了所有唯一程序代码(它们称为 pid
),我想知道是否可以自动执行此过程。 IE。编写一个运行该行但每次使用不同 pid
的脚本。
有几点值得一提:
- 我真的只有使用 R 的经验。我怀疑 python 会更好,如果这是唯一的选择,那就太公平了!
- 其中有 129,000 个要查找,所以如果可以自动执行此过程,我需要编写一个脚本,在每个新查询之间添加延迟,以免杀死 BBC 服务器!
我们非常欢迎任何有关如何处理此问题的建议。我对编程的了解非常有限,如果这是一个非常明显的问题,我深表歉意!
R 的 system
或 system2
可以很好地调用外部程序,尽管我个人更喜欢 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 在这方面与其他语言相比没有优势。