2014-10-01 84 views
0

我目前正试图从超过800,000个网址下载文件。每个网址代表.txt文件。使用python快速下载文件

我使用的数据框来存储所有

URL信息:

index  Filename           
4   .../data/1000015/0001104659-05-006777.txt 
5   .../data/1000015/0000950123-05-003812.txt 
...... 

代码:

for i in m.index: 
    download = 'ftp:/.../' + m['Filename'][i] 
    print download 
    urllib.urlretrieve(download, '%s''%s.txt' % (m['Co_name'][i], m['Date'][i])) 

这种方法可行,但是,速度是相当低它在7分钟内下载15个文件。考虑到我有超过800,000个文件。这是超过9个月...所以我想知道有谁能帮我改进这个吗?非常感谢。


经过一些真正有用的评论,我做了一些改变,下面是做多处理的好方法吗?

代码:

def download(file): 
    import ftplib 
    ftp = ftplib.FTP('XXXX') 
    ftp.login() 
    for i in m.index: 
    a = m['Filename'][i] 
    local_file = os.path.join("local_folder", '%s %s.txt' % (m['Co_name'][i], m['Data'][i])) 
    fhandle = open(local_file,'wb') 
    print fhandle 
    ftp.retrbinary('RETR '+a, fhandle.write) 
    fhandle.close() 

m=pd.read_csv('XXXX.csv', delimiter=',', index_col='index') 

pool = Pool(10) 
pool.map(download, m) 
+1

使用多个线程 – laike9m 2014-10-01 13:24:46

+0

文件的平均大小是多少? – kums 2014-10-01 13:31:51

+0

@kums,averge是100kb – Brad 2014-10-01 13:34:05

回答

1

这样,你建立的每个文件的新连接。这意味着每个没有下载任何文件的用户会损失几秒钟的时间。

您可以通过使用ftplib(https://docs.python.org/2/library/ftplib.html)来减少这种情况,它允许建立单个连接并通过此连接一个一个地检索一个文件。

不过,有时候没有数据传输。要使用最大带宽,请使用线程并行下载多个文件。但请注意,有些服务器限制了并行连接的数量。

但是,时间开销不应超过几秒,在最坏的情况下可以说5。然后,一个100kB文件大约25s非常慢。 我想你的连接速度很慢,或者服务器是。如果FTP不是标准方式,可能是在连接终止时关闭主框架的FTP服务器,并在连接建立时启动?然后,FTPlib应该有所帮助。 但是,半秒的开销意味着等待400.000秒。所以,并行下载是有道理的。

可能是,您首先尝试一个FTP客户端,如filezilla,并检查带宽是否可能。

+0

非常感谢,它更快。正如你所说,我真的应该使用多个线程。 – Brad 2014-10-01 16:22:06

+0

嗨,@sweber。我更新了我的代码。你认为这是减少时间的有效方法吗? – Brad 2014-10-01 17:22:39

+0

嗨!它应该工作。你为什么不测试它?如上所述,检查服务器是否允许并行下载10个文件。而且,一次打开10个连接并通过这些连接下载所有文件可能会更好。这是更多的代码,你必须检查它是否值得。 – sweber 2014-10-03 06:51:53