【问题标题】:python: getting a response from check_output before the command is finishedpython:在命令完成之前从 check_output 获得响应
【发布时间】:2014-06-05 20:42:35
【问题描述】:

我正在使用 python 运行Youtube-dl,这是一个用于从 YouTube 和其他网站下载视频的软件。我专门用它来从 YouTube 视频中下载音频。我可以使用 python 从 YouTube 视频中下载音频,方法是使用 check_output() 执行保存在我的计算机上的 youtube-dl.exe 文件。

以下是我编写的执行 youtube-dl 文件并下载歌曲的方法。它返回一个巨大的文本字符串,它是 youtube-dl 程序的输出。

from subprocess import check_output

#downloads the audio from a song to wherever the python script is
def getSong(songUrl):
    return check_output('C:\Users\Ben\Desktop\youtube-dl\youtube-dl.exe --max-quality FORMAT --extract-audio ' + songUrl, shell=True)

当我在 python 中运行这个方法时,它会等待命令完成,然后返回一个包含大量信息的巨大响应。这包括在下载结束时输出的一般信息,但它也(如果通过命令提示符运行)将每隔几秒提供有关下载进度的信息。问题是,在 python 中运行它时,我会在下载完成后获得所有这些进度信息。

有什么方法可以在 check_output() 方法仍在运行时获取输出?这样我就可以为下载制作一个进度条。

编辑:

更新:下面是我已经开始工作的当前代码,除了一个小例外......

import subprocess
songUrl = "http://www.youtube.com/watch?v=uO3lN-hugaQ"
process = subprocess.Popen(["C:\Users\Ben\Desktop\youtube-dl\youtube-dl.exe", "--max quality", "FORMAT", "--extract-audio", songUrl], shell=True, stdout = subprocess.PIPE)

for line in iter(process.stdout.readline, b''):
    print line,
process.communicate()

当我运行上面的这个新代码时,它将开始逐行打印信息,因为它是在执行的命令中生成的,但是所有关于下载百分比的信息都在最后打印出来。当我尝试在命令提示符下运行相同的命令时,我发现提供有关下载百分比信息的文本实际上每秒左右更改一次,而不是使用更新的信息创建新行,正如我根据输出所怀疑的那样在蟒蛇。你认为有什么办法可以解决这个问题,所以我可以获得进度条所需的信息吗?

【问题讨论】:

  • 简短的回答是:不要使用check_output(),因为它明确地等待进程首先退出。这是一个使用Popen()的实用方法;如果它不适合您的用例,请不要使用它,而是使用任何其他方便的方法或直接访问Popen()

标签: python subprocess youtube-dl


【解决方案1】:

请改用 Popen。然后您可以执行以下操作:

import subprocess
process = subprocess.Popen(["C:\Users\Ben\Desktop\youtube-dl\youtube-dl.exe", "--max-quality", "FORMAT", "--extract-audio", "songUrl"], shell=True, stdout = subprocess.PIPE)

while process.poll() is None:
    result = process.stdout.read()
    # do some calculations for percentage done

同样作为一般经验法则,您应该避免使用 shell=True 来防止潜在的安全漏洞。

【讨论】:

  • 废话,你打败了我。改为process.poll() is None 更正确。
  • 为了正确起见,谢谢。公平地说,可能还有一种更好的方法来读取输出。这完全取决于流程输出的内容以及进度条要执行的计算类型。
  • 你好!我尝试了您发布的内容并且歌曲确实下载了,但所有输出都在最后打印出来。我完全尝试了你放在那里的内容,除了我换掉了一个实际的歌曲 url 并直接在定义结果变量的下方添加了“打印结果”。我做错了什么?
  • result = process.stdout.read() 将一直读取到 EOF,因此对当前情况没有任何改善。不过,result = process.stdout.read(<some appropriate block size>) 可以解决问题。
  • @bs7280 使用 Bob 给你的代码,while process.poll() is None + print process.stdout.readline() 应该可以解决问题,不知道你为什么要使用 .communicate()结束,或者你为什么要使用iter(...) tbh。
猜你喜欢
  • 2019-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-17
  • 2020-02-16
  • 2017-09-30
  • 1970-01-01
相关资源
最近更新 更多