Python 3.x 如何使用Python获取wget命令信息?

Python 3.x 如何使用Python获取wget命令信息?,python-3.x,Python 3.x,在Linux(Ubuntu)上,当我运行wget www.example.com/file.zip-O file.zip时,我看到一个表示下载进度的进度条。如下图所示: Python中是否有方法检索我用红色包围的所有信息我的意思是,我希望在单独的Python变量中检索以下信息: 正在下载的数据量 下载速度 剩下的时间 您可以使用: 现在您只需解析line.split()输出并更改wget参数(这仅用于测试,不保存下载的数据) 这适用于使用python 3.4的windows: import

在Linux(Ubuntu)上,当我运行
wget www.example.com/file.zip-O file.zip时,我看到一个表示下载进度的进度条。如下图所示:



Python中是否有方法检索我用红色包围的所有信息

我的意思是,我希望在单独的Python变量中检索以下信息:

  • 正在下载的数据量
  • 下载速度
  • 剩下的时间
您可以使用:

现在您只需解析
line.split()
输出并更改
wget
参数(这仅用于测试,不保存下载的数据)

这适用于使用python 3.4的windows:

import subprocess
import os
import sys

wget = os.path.join("C:\\" , "Program Files (x86)", "GnuWin32", "bin", "wget.exe")

process = subprocess.Popen(
    [wget, 'http://speedtest.dal01.softlayer.com/downloads/test10.zip', '-O', 'NUL'],
    stderr=subprocess.PIPE)

started = False
for line in process.stderr:
    line = line.decode("utf-8", "replace")
    if started:
        splited = line.split()
        if len(splited) == 9:
            percentage = splited[6]
            speed = splited[7]
            remaining = splited[8]
            print("Downloaded {} with {} per second and {} left.".format(percentage, speed, remaining), end='\r')
    elif line == os.linesep:
        started = True

您可以使用
urllib
库和
reporthook
的自定义函数在Python中实现自己的
wget

def reporthook(count_blocks, block_size, total_size):
    global start_time
    if count == 0:
      start_time = time.time()
      return
    duration = time.time() - start_time
    progress_size = int(count_blocks * block_size)
    print "downloaded %f%%" % count_blocks/float(total_size)
    # etc ...

urllib.urlretrieve(url, filename, reporthook)
(另见)


这里是一个完整的Python 3实现:

因为这些信息被输出到
stderr
,所以您需要从sys.stderr读取它们。 当输出发生变化时,我们可以使用select来读取stderr。 仅供参考,以下是一个例子:

# -*- coding: utf-8 -*-
from subprocess import PIPE, Popen
import fcntl
import os
import select
import sys

proc = Popen(['wget', 'http://speedtest.london.linode.com/100MB-london.bin'], stdin = PIPE, stderr = PIPE, stdout = PIPE)

while proc.poll() == None:
    fcntl.fcntl(
            proc.stderr.fileno(),
            fcntl.F_SETFL,
            fcntl.fcntl(proc.stderr.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK,
            )

    buf = ''
    while proc.poll() == None:
        readx_err = select.select([proc.stderr.fileno()], [], [], 0.1)[0]
        if readx_err:
            chunk = proc.stderr.read().decode('utf-8')
            buf += chunk
            if '\n' in buf and '%' in buf and '.' in buf:
                print (buf.strip().split())
                buf = ''
        else:
            break
proc.wait()

非常感谢。我运行代码时没有错误(除了
elif行==
=
之外)。该文件已下载。但是,当我添加
打印(速度)
打印(剩余)
打印(百分比)
时,不会打印任何内容。我还想知道
while
循环是否不是正确的东西?你说的“没有打印”是什么意思?(一个空行?)不是空行,事实上,当我运行
python download.py
时,shell被停止,直到下载完成,然后我得到了一个手动按钮,如果我想要的话,可以键入一些内容。但没有新的行或空行打印。没有错误,没有警告。在windows上,wget写入到stderr(我认为在unix上也是如此)。我将我的答案更新为工作版本。仍然需要解析拆分行的输出。完美。这正是我想要的。非常感谢你。
# -*- coding: utf-8 -*-
from subprocess import PIPE, Popen
import fcntl
import os
import select
import sys

proc = Popen(['wget', 'http://speedtest.london.linode.com/100MB-london.bin'], stdin = PIPE, stderr = PIPE, stdout = PIPE)

while proc.poll() == None:
    fcntl.fcntl(
            proc.stderr.fileno(),
            fcntl.F_SETFL,
            fcntl.fcntl(proc.stderr.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK,
            )

    buf = ''
    while proc.poll() == None:
        readx_err = select.select([proc.stderr.fileno()], [], [], 0.1)[0]
        if readx_err:
            chunk = proc.stderr.read().decode('utf-8')
            buf += chunk
            if '\n' in buf and '%' in buf and '.' in buf:
                print (buf.strip().split())
                buf = ''
        else:
            break
proc.wait()