ibiz
Оффтопик:
уверен, что по скорости и расходу ресурсов рнр+curl не уступает самопальному скрипту на с++
ну вот попробуй такая скорость устроит:
<?
//ini_set('memory_limit', '512M');
//@ignore_user_abort(true);
//@set_time_limit(90);
$starttime = 0;
$starttime = explode(' ', microtime());
$starttime = $starttime[0] + $starttime[1];
$urls = array(
'http://translate.google.com/',
'http://slovari.yandex.ru/',
'http://dic.academic.ru/',
'http://www.translate.ru/',
'http://www.multitran.ru/',
'http://www.lingvo.ru/',
'http://psi.webzone.ru/',
'http://www.glossary.ru/',
'http://ru.wiktionary.org/',
'http://mirslovarei.com/'
);
echo '<xmp>'.print_r($urls,1).'</xmp>';
$contents = multi_get_url($urls);
foreach($contents as $i=>$content){
file_put_contents(dirname(__FILE__).'/tmp/'.$i.'.txt', $content);
}
function multi_get_url($urls){
global $headers,$cookie_file,$ua_list;
$mh = curl_multi_init();
$ua_list = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.24) Gecko/20111103 Firefox/3.6.24 sputnik 2.4.0.49';
foreach($urls as $i => $url){
$conn[$i]=curl_init($url);
curl_setopt($conn[$i], CURLOPT_POST, 0);
curl_setopt($conn[$i], CURLOPT_HEADER, 1);
curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($conn[$i], CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($conn[$i], CURLOPT_MAXREDIRS, 0);
curl_setopt($conn[$i], CURLOPT_TIMEOUT, 60);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($conn[$i], CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_multi_add_handle ($mh,$conn[$i]);
}
do{ $n=curl_multi_exec($mh,$active); } while ($active);
foreach($urls as $i => $url) {
$content[$i]=curl_multi_getcontent($conn[$i]);
if(isset($content[$i]))$aCURLinfo[$i] = curl_getInfo($conn[$i]);
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
return $content;
}
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$gentime = round(($endtime - $starttime), 4);
echo "<br>time: ".$gentime;
exit;
?>
Salvator
на c++ будет дорого и трудноподдерживаемо. рекомендую python multi-threading. фактически, та же асинхронная загрузка, но будет работать везде
что-то такое, накидал за 5 минут
:
Код:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urllib2
import sys
from threading import Thread
class Downloader(Thread):
def __init__(self, url):
Thread.__init__(self)
self.url = url
self.out_file = url.split('/')[-1]
def run(self):
print '>', self.url, 'starting'
f = open(self.out_file, 'wb', 8096)
u = urllib2.urlopen(self.url)
data = u.read(8096)
size = 0
while data:
f.write(data)
size += len(data)
print '>', self.url, size, 'bytes'
data = u.read(8096)
f.close()
print '>', self.url, 'received', size, 'bytes'
if __name__ == '__main__':
if len(sys.argv) != 2:
print 'Use %s urllist.txt' % sys.argv[0]
sys.exit(1)
pool = []
for l in open(sys.argv[1]).readlines():
l = l.strip()
t = Downloader(l)
pool.append(t)
t.start()
print 'Waiting threads'
for t in pool:
t.join()
запуск - python downloader.py ulist.txt,
в ulist - список урлов по одному на строку. следи, чтобы имена файлов в урлах не повторялись для текущего каталога.
mr. snatch
да дело не в винтах, на пыхе - ясен будет медленнее) в его случае, пока мультикурл полностью не отработает для текущего набора подзаданий, управление назад в скрипт он не вернёт, там "события" нужно эмулировать и самому всё дёргать, кроме того
А в случае Пайтона это происходит потому, как Global Lock JIT-а, что б его, но в целом, это один из тех немногих случаев, для которых нужна истинная true-многопоточность, и когда она действительно нужна, можно использовать multiprocessing, фактически, это тот же форк, но только не wget-а а самого себя. Ясен, всегда нужно синхронизироваться и т.д. но для этого случая, сойдёт и так (ну или просто queue, multiprocessing.Pool и т .д.)
это:
Код:
from threading import Thread
class Downloader(Thread):
def __init__(self, url):
Thread.__init__(self)
замени на:
Код:
from multiprocessing import Process
class Downloader(Process):
def __init__(self, url):
super(Downloader, self).__init__()
ну а вообще нужно свой событийный пул делать, и подкидывать новые задания, когда какое-то одно отработает