【问题标题】:wget Vs urlretrieve of pythonpython的wget与urlretrieve
【发布时间】:2009-06-10 10:18:59
【问题描述】:

我的任务是从网站下载 Gbs 的数据。数据为 .gz 文件,每个文件大小为 45mb。

获取文件的简单方法是使用“wget -r -np -A files url”。这将以递归格式下载数据并镜像网站。下载速率非常高,4mb/秒。

但是,为了玩耍,我还使用 python 来构建我的 urlparser。

通过 Python 的 urlretrieve 下载速度非常慢,可能是 wget 的 4 倍。下载速率为 500kb/秒。我使用 HTMLParser 来解析 href 标签。

我不确定为什么会这样。有什么设置吗?

谢谢

【问题讨论】:

  • 你试过比较 CPU 使用率和 tcpdump 输出吗?
  • 什么是 tcpdump?如何获得?
  • 我会忽略传输速度(兆字节/MB 和兆比特/Mb 完全不同!)并使用命令time wget http://example.com/filetime python urlretrieve_downloader.py 比较两者
  • 啊,我的意思是 500Kb 而已.. 对不起小写...我的错... 都是字节。 .. .5MB/秒和 4Mb/秒
  • 两者都以字节为单位?所以你有一个32兆的连接?可能不是。我很确定它是 500 KB 和 4 兆位。似乎太方便了,无法精确减速 1/8。

标签: python urllib2 wget


【解决方案1】:

可能是您的单位数学错误。

只是注意到500KB/s (kilobytes) is equal to 4Mb/s (megabits)

【讨论】:

    【解决方案2】:

    urllib 对我的工作速度与 wget 一样快。试试这个代码。它与 wget 一样以百分比显示进度。

    import sys, urllib
    def reporthook(a,b,c): 
        # ',' at the end of the line is important!
        print "% 3.1f%% of %d bytes\r" % (min(100, float(a * b) / c * 100), c),
        #you can also use sys.stdout.write
        #sys.stdout.write("\r% 3.1f%% of %d bytes" 
        #                 % (min(100, float(a * b) / c * 100), c)
        sys.stdout.flush()
    for url in sys.argv[1:]:
         i = url.rfind('/')
         file = url[i+1:]
         print url, "->", file
         urllib.urlretrieve(url, file, reporthook)
    

    【讨论】:

      【解决方案3】:

      至于 html 解析,您可能会得到的最快/最简单的方法是使用 lxml 至于 http 请求本身:httplib2 非常易于使用,并且可能会加快下载速度,因为它支持 http 1.1 keep-alive 连接和 gzip 压缩。还有pycURL,它声称速度非常快(但更难使用),并且基于 curllib,但我从未使用过。

      您也可以尝试同时下载不同的文件,但请记住,过度优化下载时间可能对相关网站不太礼貌。

      抱歉缺少超链接,但 SO 告诉我“对不起,新用户最多只能发布一个超链接”

      【讨论】:

      • 为 ya, newb 添加了一些链接 :)
      • 我不确定解析是否是问题......它正在检索和存储导致延迟的文件......
      【解决方案4】:

      传输速度很容易产生误导。您能否尝试使用以下脚本,该脚本仅使用 wgeturllib.urlretrieve 下载相同的 URL - 运行几次,以防您使用缓存第二次尝试的 URL。

      对于小文件,由于外部进程的启动时间,wget 会花费稍长的时间,但对于应该无关紧要的大文件。

      from time import time
      import urllib
      import subprocess
      
      target = "http://example.com" # change this to a more useful URL
      
      wget_start = time()
      
      proc = subprocess.Popen(["wget", target])
      proc.communicate()
      
      wget_end = time()
      
      
      url_start = time()
      urllib.urlretrieve(target)
      url_end = time()
      
      print "wget -> %s" % (wget_end - wget_start)
      print "urllib.urlretrieve -> %s"  % (url_end - url_start)
      

      【讨论】:

        【解决方案5】:

        也许你可以 wget 然后在 Python 中检查数据?

        【讨论】:

        • 对不起,我不明白你的意思..你是说从 python 代码调用 wget 吗?
        • 你可以这样做,或者从 shell,利用快速的下载速度......然后使用 Python 处理数据。
        【解决方案6】:
        import subprocess
        
        myurl = 'http://some_server/data/'
        subprocess.call(["wget", "-r", "-np", "-A", "files", myurl])
        

        【讨论】:

          【解决方案7】:

          由于python建议使用urllib2而不是urllib,我在urllib2.urlopenwget之间进行测试。

          结果是,他们两个下载同一个文件所需的时间几乎相同。有时,urllib2 的性能更好。

          wget 的优势在于动态进度条在传输时显示完成百分比和当前下载速度。

          我测试的文件大小是5MB。我没有在python中使用任何缓存模块,我不知道wget在下载大文件时是如何工作的。

          【讨论】:

            【解决方案8】:

            真的应该没有区别。 urlretrieve 所做的只是发出一个简单的 HTTP GET 请求。你有没有拿出你的数据处理代码,直接对 wget 和纯 python 的吞吐量进行比较?

            【讨论】:

              【解决方案9】:

              请给我们看一些代码。我很确定它必须与代码一起,而不是在 urlretrieve 上。

              我过去曾使用过它,从未遇到过任何与速度相关的问题。

              【讨论】:

              【解决方案10】:

              您可以使用wget -k 在所有网址中加入相关链接。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-11-22
                • 1970-01-01
                • 2020-04-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多