免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4502 | 回复: 8
打印 上一主题 下一主题

python 分块多线程下载问题 [复制链接]

论坛徽章:
1
2015亚冠之西悉尼流浪者
日期:2015-05-28 16:30:37
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-11-20 16:48 |只看该作者 |倒序浏览
本帖最后由 tank064 于 2013-11-20 18:04 编辑

hello 最近在倒腾一个可以post提交用户名密码的下载脚本,
在网上搜索了下,找到不少相关文章.
下面是一段代码
  1. class AxelPython(Thread, urllib.FancyURLopener):
  2.     '''Multi-thread downloading class.

  3.         run() is a vitural method of Thread.
  4.     '''

  5.     def __init__(self, threadname, url, filename, ranges=0, proxies={}):
  6.         Thread.__init__(self, name=threadname)
  7.         urllib.FancyURLopener.__init__(self, proxies)
  8.         self.name = threadname
  9.         self.url1 = url
  10.         self.url = self.url1
  11.         self.filename = filename
  12.         self.ranges = ranges
  13.         self.downloaded = 0

  14.     def run(self):
  15.         '''vertual function in Thread'''
  16.         try:
  17.             self.downloaded = os.path.getsize(self.filename)
  18.         except OSError:
  19.             #print 'never downloaded'
  20.             self.downloaded = 0

  21.         # rebuild start poind
  22.         self.startpoint = self.ranges[0] + self.downloaded

  23.         # This part is completed
  24.         if self.startpoint >= self.ranges[1]:
  25.             print 'Part %s has been downloaded over.' % self.filename
  26.             return

  27.         self.oneTimeSize = 16384 #16kByte/time
  28.         print 'task %s will download from %d to %d' % (self.name, self.startpoint, self.ranges[1])

  29.         self.addheader("Range", "bytes=%d-%d" % (self.startpoint, self.ranges[1]))

  30.         self.urlhandle = self.open(self.url)

  31.         data = self.urlhandle.read(self.oneTimeSize)
  32.         while data:
  33.             filehandle = open(self.filename, 'ab+')
  34.             filehandle.write(data)
  35.             filehandle.close()

  36.             self.downloaded += len(data)
  37.             #print "%s" % (self.name)
  38.             #progress = u'\r...'

  39.             data = self.urlhandle.read(self.oneTimeSize)
复制代码
在自己机器上运行时发现, addheader后, 每一个线程就卡在这里了 self.urlhandle = self.open(self.url)

请问该如何解决?(2楼是完整代码)

论坛徽章:
1
2015亚冠之西悉尼流浪者
日期:2015-05-28 16:30:37
2 [报告]
发表于 2013-11-20 16:49 |只看该作者
  1. #!/usr/bin/env python
  2. #coding: utf-8
  3. #Python_version: 2.7


  4. '''It is a multi-thread downloading tool

  5.     It was developed follow axel.
  6.         Author: volans
  7.         E-mail: volansw [at] gmail.com
  8. '''

  9. import sys
  10. import os
  11. import time
  12. import urllib
  13. from threading import Thread

  14. #local_proxies = {'http': 'http://131.139.58.200:8080'}
  15. local_proxies = {}

  16. class AxelPython(Thread, urllib.FancyURLopener):
  17.     '''Multi-thread downloading class.

  18.         run() is a vitural method of Thread.
  19.     '''

  20.     def __init__(self, threadname, url, filename, ranges=0, proxies={}):
  21.         Thread.__init__(self, name=threadname)
  22.         urllib.FancyURLopener.__init__(self, proxies)
  23.         self.name = threadname
  24.         self.url1 = url
  25.         self.url = self.url1
  26.         self.filename = filename
  27.         self.ranges = ranges
  28.         self.downloaded = 0

  29.     def run(self):
  30.         '''vertual function in Thread'''
  31.         try:
  32.             self.downloaded = os.path.getsize(self.filename)
  33.         except OSError:
  34.             #print 'never downloaded'
  35.             self.downloaded = 0

  36.         # rebuild start poind
  37.         self.startpoint = self.ranges[0] + self.downloaded

  38.         # This part is completed
  39.         if self.startpoint >= self.ranges[1]:
  40.             print 'Part %s has been downloaded over.' % self.filename
  41.             return

  42.         self.oneTimeSize = 16384 #16kByte/time
  43.         print 'task %s will download from %d to %d' % (self.name, self.startpoint, self.ranges[1])

  44.         self.addheader("Range", "bytes=%d-%d" % (self.startpoint, self.ranges[1]))

  45.         self.urlhandle = self.open(self.url)

  46.         data = self.urlhandle.read(self.oneTimeSize)
  47.         while data:
  48.             filehandle = open(self.filename, 'ab+')
  49.             filehandle.write(data)
  50.             filehandle.close()

  51.             self.downloaded += len(data)
  52.             #print "%s" % (self.name)
  53.             #progress = u'\r...'

  54.             data = self.urlhandle.read(self.oneTimeSize)


  55. def GetUrlFileSize(url, proxies={}):
  56.     urlHandler = urllib.urlopen(url, proxies=proxies)
  57.     headers = urlHandler.info().headers
  58.     length = 0
  59.     for header in headers:
  60.         if header.find('Length') != -1:
  61.             length = header.split(':')[-1].strip()
  62.             length = int(length)
  63.     return length


  64. def SpliteBlocks(totalsize, blocknumber):
  65.     blocksize = totalsize / blocknumber
  66.     ranges = []
  67.     for i in range(0, blocknumber - 1):
  68.         ranges.append((i * blocksize, i * blocksize + blocksize - 1))
  69.     ranges.append(( blocksize * (blocknumber - 1), totalsize - 1 ))

  70.     return ranges


  71. def islive(tasks):
  72.     for task in tasks:
  73.         if task.isAlive():
  74.             return True
  75.     return False


  76. def paxel(url, output, blocks=6, proxies=local_proxies):
  77.     ''' paxel
  78.     '''
  79.     size = GetUrlFileSize(url, proxies)
  80.     ranges = SpliteBlocks(size, blocks)

  81.     threadname = ["thread_%d" % i for i in range(0, blocks)]
  82.     filename = ["tmpfile_%d" % i for i in range(0, blocks)]

  83.     tasks = []
  84.     for i in range(0, blocks):
  85.         task = AxelPython(threadname[i], url, filename[i], ranges[i])
  86.         task.setDaemon(True)
  87.         task.start()
  88.         tasks.append(task)

  89.     time.sleep(2)
  90.     while islive(tasks):
  91.         downloaded = sum([task.downloaded for task in tasks])
  92.         process = downloaded / float(size) * 100
  93.         show = u'\rFilesize:%d Downloaded:%d Completed:%.2f%%' % (size, downloaded, process)
  94.         sys.stdout.write(show)
  95.         sys.stdout.flush()
  96.         time.sleep(0.5)

  97.     filehandle = open(output, 'wb+')
  98.     for i in filename:
  99.         f = open(i, 'rb')
  100.         filehandle.write(f.read())
  101.         f.close()
  102.         try:
  103.             os.remove(i)
  104.             pass
  105.         except:
  106.             pass

  107.     filehandle.close()


  108. if __name__ == '__main__':
  109.     url = "http://download-ln.jetbrains.com/python/pycharm-professional-3.0.1.exe"
  110.     output = 'package.zip'
  111.     paxel(url, output, blocks=4, proxies={})
复制代码

论坛徽章:
0
3 [报告]
发表于 2013-11-20 19:27 |只看该作者
代码还没看,能先解释一下什么叫“post提交用户名密码的下载脚本”吗?

论坛徽章:
4
白羊座
日期:2013-11-05 10:26:09冥斗士
日期:2015-11-17 14:19:55白银圣斗士
日期:2015-11-17 15:13:0815-16赛季CBA联赛之新疆
日期:2016-04-01 09:10:58
4 [报告]
发表于 2013-11-20 20:32 |只看该作者
没有看到POST用户名密码什么的,只是看到了多线程下载。

论坛徽章:
1
2015亚冠之西悉尼流浪者
日期:2015-05-28 16:30:37
5 [报告]
发表于 2013-11-21 06:54 |只看该作者
就时下载时需要输入用户名, 密码啊
不过贴在上面的代码还没有没有用到post
就像 wget  --post-data=     或者 --post-file=
回复 3# laike9m


   

论坛徽章:
1
2015亚冠之西悉尼流浪者
日期:2015-05-28 16:30:37
6 [报告]
发表于 2013-11-21 06:56 |只看该作者
恩 着时还只是普通下载, 没有加入post,   可时着段代码下载时 在 header里 指定  Range 后, 请求就没有回应了,  所以来论坛 问问呢
回复 4# icymirror


   

论坛徽章:
4
白羊座
日期:2013-11-05 10:26:09冥斗士
日期:2015-11-17 14:19:55白银圣斗士
日期:2015-11-17 15:13:0815-16赛季CBA联赛之新疆
日期:2016-04-01 09:10:58
7 [报告]
发表于 2013-11-21 09:42 |只看该作者
回复 6# tank064


    在我的机器上用Windows Server 2008 + IIS + pdf(下载目标) + Python 2.7.5 + 你的脚本 试验通过。
    所以,至少代码的基本功能应当没有大问题,所以,有可能你需要了解下目标服务器是不是支持多点下载等几个下载相关的设置,这个有可能是个问题。
    如果不支持,服务器不返回对应的结果应当也是可以理解的--防止资源被盗嘛,呵呵。

论坛徽章:
16
IT运维版块每日发帖之星
日期:2015-10-02 06:20:00IT运维版块每月发帖之星
日期:2015-09-11 19:30:52IT运维版块每周发帖之星
日期:2015-09-11 19:20:31IT运维版块每日发帖之星
日期:2015-08-26 06:20:00每日论坛发贴之星
日期:2015-08-20 06:20:00IT运维版块每日发帖之星
日期:2015-08-20 06:20:002015年辞旧岁徽章
日期:2015-03-03 16:54:15金牛座
日期:2014-05-04 16:58:09双子座
日期:2013-12-17 16:44:37辰龙
日期:2013-11-22 15:20:59狮子座
日期:2013-11-18 22:55:08射手座
日期:2013-11-12 10:54:26
8 [报告]
发表于 2013-11-21 15:38 |只看该作者
wget --random -user -password -U browser 也能满足你把?

论坛徽章:
1
2015亚冠之西悉尼流浪者
日期:2015-05-28 16:30:37
9 [报告]
发表于 2013-11-22 00:52 |只看该作者
..我ubuntu上的wget没有你说的那个选项回复 8# wenhq


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP