Python相当于给定的wget命令

Sov*_*ero 53 python wget

我正在尝试创建一个与此wget命令完全相同的Python函数:

wget -c --read-timeout=5 --tries=0 "$URL"
Run Code Online (Sandbox Code Playgroud)

-c - 如果下载中断,请从中断处继续.

--read-timeout=5 - 如果超过5秒没有新数据进入,请放弃并重试.鉴于-c这意味着它将从它停止的地方再次尝试.

--tries=0 - 永远重试.

串联使用的这三个参数导致下载不会失败.

我想在我的Python脚本中复制这些功能,但我不知道从哪里开始......

Bla*_*g23 78

还有一个很好的Python模块wget,它很容易使用.在这里找到.

这表明了设计的简洁性:

>>> import wget
>>> url = 'http://www.futurecrew.com/skaven/song_files/mp3/razorback.mp3'
>>> filename = wget.download(url)
100% [................................................] 3841532 / 3841532>
>> filename
'razorback.mp3'
Run Code Online (Sandbox Code Playgroud)

请享用.

但是,如果wget不起作用(我遇到某些PDF文件有问题),请尝试此解决方案.

编辑:您还可以使用该out参数来使用自定义输出目录而不是当前工作目录.

>>> output_directory = <directory_name>
>>> filename = wget.download(url, out=output_directory)
>>> filename
'razorback.mp3'
Run Code Online (Sandbox Code Playgroud)

  • 很抱歉迟到的回复,由于某种原因没有看到此通知.你最需要'pip install wget`. (3认同)
  • @AshishKarpe 如果您使用的是 Ubuntu,请尝试 sudo apt-get install python3-wget。 (3认同)
  • `wget` 的选项很少,而且似乎没有维护。“requests”在各个方面都更优越。 (2认同)
  • @Blairg23同时,python wget 包明确表示,它的选项与原始的“wget”实用程序不兼容。仅供参考,您甚至无法设置 User-Agent 标头,可以吗? (2认同)

Eug*_*e K 28

urllib.request应该工作.只需将其设置为while(未完成)循环,检查本地文件是否已存在,是否确实发送带有RANGE标头的GET,指定下载本地文件的程度.确保使用read()附加到本地文件,直到发生错误.

这也可能是Python的重复urllib2恢复下载在网络重新连接时不起作用

  • @XamuelDvorak你真的输入了一个URL吗?url需要类型,例如`http://`,`ftp://`. (2认同)

Puj*_*ava 16

import urllib2

attempts = 0

while attempts < 3:
    try:
        response = urllib2.urlopen("http://example.com", timeout = 5)
        content = response.read()
        f = open( "local/index.html", 'w' )
        f.write( content )
        f.close()
        break
    except urllib2.URLError as e:
        attempts += 1
        print type(e)
Run Code Online (Sandbox Code Playgroud)


小智 14

对于WindowsPython 3.x,我在下载时重命名文件的两分钱贡献:

  1. 安装wget模块:pip install wget
  2. 使用 wget :
import wget
wget.download('Url', 'C:\\PathToMyDownloadFolder\\NewFileName.extension')
Run Code Online (Sandbox Code Playgroud)

真正有效的命令行示例:

python -c "import wget; wget.download(""https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.17.2.tar.xz"", ""C:\\Users\\TestName.TestExtension"")"
Run Code Online (Sandbox Code Playgroud)

注意:“C:\\PathToMyDownloadFolder\\NewFileName.extension”不是强制性的。默认情况下,文件不会重命名,下载文件夹是您的本地路径。


Wil*_*ton 10

我不得不在一个没有正确的选项编译成wget的linux版本上做这样的事情.此示例用于下载内存分析工具'guppy'.我不确定它是否重要,但我保持目标文件的名称与url目标名称相同...

这是我想出的:

python -c "import requests; r = requests.get('https://pypi.python.org/packages/source/g/guppy/guppy-0.1.10.tar.gz') ; open('guppy-0.1.10.tar.gz' , 'wb').write(r.content)"
Run Code Online (Sandbox Code Playgroud)

这是单行,这里更具可读性:

import requests
fname = 'guppy-0.1.10.tar.gz'
url = 'https://pypi.python.org/packages/source/g/guppy/' + fname
r = requests.get(url)
open(fname , 'wb').write(r.content)
Run Code Online (Sandbox Code Playgroud)

这适用于下载tarball.我能够提取包并在下载后下载它.

编辑:

为了解决问题,这里是一个带有打印到STDOUT的进度条的实现.没有clint包装可能有一种更便携的方式来做到这一点,但这已在我的机器上测试并且工作正常:

#!/usr/bin/env python

from clint.textui import progress
import requests

fname = 'guppy-0.1.10.tar.gz'
url = 'https://pypi.python.org/packages/source/g/guppy/' + fname

r = requests.get(url, stream=True)
with open(fname, 'wb') as f:
    total_length = int(r.headers.get('content-length'))
    for chunk in progress.bar(r.iter_content(chunk_size=1024), expected_size=(total_length/1024) + 1): 
        if chunk:
            f.write(chunk)
            f.flush()
Run Code Online (Sandbox Code Playgroud)

  • 有什么方法可以显示文件下载的进度吗? (4认同)

Yoh*_*dia 9

我经常发现更简单,更可靠的解决方案是在python中简单地执行终端命令。在您的情况下:

import os
url = 'https://www.someurl.com'
os.system(f"""wget -c --read-timeout=5 --tries=0 "{url}"""")
Run Code Online (Sandbox Code Playgroud)

  • 使用“子进程”。**始终**使用“子流程”。使用像这样的“os.system”进行远程用户输入的机器很容易被攻击。 (12认同)
  • 当我被否决时,特别是因为提供了一种完全不同的方法,我想知道为什么。小心解释? (6认同)
  • @gomennathan 不在*这种*情况下,其中 url 恰好在上一行上进行了硬编码;但如果“url”来自用户输入(这太常见了),那么只需提供类似“https://www.google.com”的内容就足够了;python3 -c“反向 shell 代码”;echo“Powned”;反向 shell 的代码可以是这样的:https://medium.com/@songchai.d01/how-to-create-a-reverse-shell-in-python-41fe75d88521 (3认同)
  • @gomennathan 那么你建议如何使用“urlparse”验证 url? (3认同)
  • 看起来 os.system 的 args 被不正确地转义了。一个“最后太多了。此外,它在 Windows 上不起作用,因为它没有 wget。为此,你需要去这里:https://eternallybored.org/misc/wget/ 下载它并将其添加到环境(路径)。不过很好的解决方案,upvoting ;) (2认同)

Shi*_*hah 7

这是从torchvision 库中采用的代码:

import urllib

def download_url(url, root, filename=None):
    """Download a file from a url and place it in root.
    Args:
        url (str): URL to download file from
        root (str): Directory to place downloaded file in
        filename (str, optional): Name to save the file under. If None, use the basename of the URL
    """

    root = os.path.expanduser(root)
    if not filename:
        filename = os.path.basename(url)
    fpath = os.path.join(root, filename)

    os.makedirs(root, exist_ok=True)

    try:
        print('Downloading ' + url + ' to ' + fpath)
        urllib.request.urlretrieve(url, fpath)
    except (urllib.error.URLError, IOError) as e:
        if url[:5] == 'https':
            url = url.replace('https:', 'http:')
            print('Failed download. Trying https -> http instead.'
                    ' Downloading ' + url + ' to ' + fpath)
            urllib.request.urlretrieve(url, fpath)
Run Code Online (Sandbox Code Playgroud)

如果您可以依赖 torchvision 库,那么您也只需执行以下操作:

from torchvision.datasets.utils import download_url
download_url('http://something.com/file.zip', '~/my_folder`)
Run Code Online (Sandbox Code Playgroud)