Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不提供文件名的Python下载_Python_Download_Urllib2_Urllib - Fatal编程技术网

不提供文件名的Python下载

不提供文件名的Python下载,python,download,urllib2,urllib,Python,Download,Urllib2,Urllib,如何使用python下载带有进度报告的文件,但不提供文件名 import urllib, urlparse split = urlparse.urlsplit(url) filename = "/tmp/" + split.path.split("/")[-1] urllib.urlretrieve(url, filename) 我尝试了urllib.urlretrieve,但似乎必须为下载的文件提供一个文件名才能另存为 例如: 我不想提供这个: urllib.urlretrieve("ht

如何使用python下载带有进度报告的文件,但不提供文件名

import urllib, urlparse

split = urlparse.urlsplit(url)
filename = "/tmp/" + split.path.split("/")[-1]
urllib.urlretrieve(url, filename)
我尝试了urllib.urlretrieve,但似乎必须为下载的文件提供一个文件名才能另存为

例如:

我不想提供这个:

urllib.urlretrieve("http://www.mozilla.com/products/download.html?product=firefox-3.6.3&os=win&lang=en-US", "/tmp/firefox.exe")
仅此而已:

urllib.urlretrieve("http://www.mozilla.com/products/download.html?product=firefox-3.6.3&os=win&lang=en-US", "/tmp/")
但如果我这样做了,我会得到这个错误:

IOError: [Errno 21] Is a directory: '/tmp'
也无法从某些URL获取文件名 例如:

有,它创建了一个类似文件的对象,可用于读取数据,而无需将数据保存到本地文件:

from urllib2 import urlopen

f = urlopen("http://example.com/")
for line in f:
  print len(line)
f.close()

(我不确定这是否是你想要的。)

问题澄清后编辑

urlparse.urlspilt
将获取您正在打开的url并将其拆分为其组成部分,然后您可以获取
路径
部分并使用最后一个
/
分隔的区块作为文件名

import urllib, urlparse

split = urlparse.urlsplit(url)
filename = "/tmp/" + split.path.split("/")[-1]
urllib.urlretrieve(url, filename)

您指定的URL根本不引用文件。这是一个指向网页的重定向,该网页运行一些javascript,使您的web浏览器下载该文件。我的浏览器从相关URL定向到(镜像)的实际地址是:

http://mozilla.mirrors.evolva.ro//firefox/releases/3.6.3/win32/en-US/Firefox%20Setup%203.6.3.exe
我相信有两种方式可以让web服务器指定下载文件的名称

  • URL路径的最后一段
  • 标题,可以指定要使用的其他文件名

  • 对于要下载的文件,我认为您只需要URL的最后一个路径段(但使用文件的实际URL,而不是选择要使用哪个镜像文件的网页)。但对于某些下载,您需要从
    内容处置
    标题获取要使用的文件名

    快速查看firefox页面上的javascript会发现:

    // 2. Build download.mozilla.org URL out of those vars.
    download_url = "http://download.mozilla.org/?product=";
    download_url += product + '&os=' + os + '&lang=' + lang;
    
    因此,只需将您的url更改为:

    http://www.mozilla.com/products/download.html?product=firefox-3.6.3&os=win&lang=en-US
    

    所以现在我将检查标题,看看我们真正得到了什么

    $ curl -I "http://download.mozilla.org/?product=firefox-3.6.3&os=win&lang=en-US"
    HTTP/1.1 302 Found
    Server: Apache
    X-Backend-Server: pp-app-dist09
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, private
    Content-Type: text/html; charset=UTF-8
    Date: Sat, 08 May 2010 21:02:50 GMT
    Location: http://mozilla.mirror.ac.za/firefox/releases/3.6.3/win32/en-US/Firefox Setup 3.6.3.exe
    Pragma: no-cache
    Transfer-Encoding: chunked
    Connection: Keep-Alive
    Set-Cookie: dmo=10.8.84.200.1273352570769772; path=/; expires=Sun, 08-May-11 21:02:50 GMT
    X-Powered-By: PHP/5.1.6
    
    这实际上是一个302重定向,现在使用Location头中的内容作为新url来获取实际文件。您需要自己弄清楚如何执行请求并阅读标题(对不起,我没有太多时间)。解析位置标头后,您可以使用正则表达式剥离位置的其余部分,以获取文件名,并将文件保存到:

    >>> location = 'http://mozilla.mirror.ac.za/firefox/releases/3.6.3/win32/en-US/Firefox Setup 3.6.3.exe'
    >>> re.match('^.*/(.*?)$', location).groups()[0]
    'Firefox Setup 3.6.3.exe'
    
    因此,要获得实际的文件名,您需要自己遵循302。所需的代码我将留给您,但希望这将为您指明正确的方向。

    将使用传递给它的URL的basename作为文件名。请注意,它将忽略
    内容处置
    标题。

    我以

    os.system('wget -P /tmp http://www.mozilla.com/products/download.html?'
              'product=firefox-3.6.3&os=win&lang=en-US')
    

    以下是使用python3和url中未指定文件名的完整方法:

    from urllib.request import urlopen
    from urllib.request import urlretrieve
    import cgi
    
    url = "http://cloud.ine.ru/s/JDbPr6W4QXnXKgo/download"
    remotefile = urlopen(url)
    blah = remotefile.info()['Content-Disposition']
    value, params = cgi.parse_header(blah)
    filename = params["filename"]
    urlretrieve(url, filename)
    

    结果你应该得到
    cargo\u live\u animals\u parrot.jpg
    文件

    如果你不知道下载什么,你怎么能下载?你需要一些标识符。请澄清您的问题。对不起,我指的是一个文件名,供下载保存为。我知道网址。我希望这是有意义的。不确定我是否理解你的问题:你想从给定的URL提取一个文件名,然后将其用作用户定义目录下的文件名?不完全是,我刚刚用一个示例编辑了我的问题,希望这有助于感谢你的回答。问题是此URL不包含文件名。谢谢你的回复!那么,当图像URL不包含扩展名时,您是如何解决的呢?可能您应该添加--trust server names开关,以便wget使用Content Disposition提供的名称。这是最好的答案,因为它考虑到服务器可以选择与URL完全不同的文件名。
    import shutil
    import urllib.parse
    import urllib.request
    import os
    
    urls = {
        'just_filename' : 'https://github.com/bits4waves/100daysofpractice-dataset/raw/master/requirements.txt',
        'filename_with_params' : 'https://github.com/bits4waves/resonometer/blob/master/sound/violin-A-pluck.wav?raw=true',
        'no_filename' : 'https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US',
    }
    
    for url in urls.values():
        with urllib.request.urlopen(url) as response:
            parsed_url_path = urllib.parse.urlparse(response.url).path
            filename = os.path.basename(parsed_url_path)
            with open(filename, 'w+b') as f:
                shutil.copyfileobj(response, f)