2016-12-07 6 views
1

Я пишу программу, которая должна загружать кучу файлов из Интернета, прежде чем она сможет даже запустить, поэтому я создал функцию, которая будет загружать все файлы и " инициализировать " программу под названием init_program, как она работает, она проходит через пару dicts, которые имеют URL-адреса для gistfiles на github. Он тянет URL-адреса и использует urllib2 для их загрузки. Я не смогу добавить все файлы, но вы можете попробовать, клонируя репо here. Вот функция, которая будет создавать файлы из гов:Ускорение скорости загрузки файлов из Интернета

def init_program(): 
    """ Initialize the program and allow all the files to be downloaded 
     This will take awhile to process, but I'm working on the processing 
     speed """ 

    downloaded_wordlists = [] # Used to count the amount of items downloaded 
    downloaded_rainbow_tables = [] 

    print("\n") 
    banner("Initializing program and downloading files, this may take awhile..") 
    print("\n") 

    # INIT_FILE is a file that will contain "false" if the program is not initialized 
    # And "true" if the program is initialized 
    with open(INIT_FILE) as data: 
     if data.read() == "false": 
      for item in GIST_DICT_LINKS.keys(): 
       sys.stdout.write("\rDownloading {} out of {} wordlists.. ".format(len(downloaded_wordlists) + 1, 
                        len(GIST_DICT_LINKS.keys()))) 
       sys.stdout.flush() 
       new_wordlist = open("dicts/included_dicts/wordlists/{}.txt".format(item), "a+") 
       # Download the wordlists and save them into a file 
       wordlist_data = urllib2.urlopen(GIST_DICT_LINKS[item]) 
       new_wordlist.write(wordlist_data.read()) 
       downloaded_wordlists.append(item + ".txt") 
       new_wordlist.close() 

      print("\n") 
      banner("Done with wordlists, moving to rainbow tables..") 
      print("\n") 

      for table in GIST_RAINBOW_LINKS.keys(): 
       sys.stdout.write("\rDownloading {} out of {} rainbow tables".format(len(downloaded_rainbow_tables) + 1, 
                        len(GIST_RAINBOW_LINKS.keys()))) 
       new_rainbowtable = open("dicts/included_dicts/rainbow_tables/{}.rtc".format(table)) 
       # Download the rainbow tables and save them into a file 
       rainbow_data = urllib2.urlopen(GIST_RAINBOW_LINKS[table]) 
       new_rainbowtable.write(rainbow_data.read()) 
       downloaded_rainbow_tables.append(table + ".rtc") 
       new_rainbowtable.close() 

      open(data, "w").write("true").close() # Will never be initialized again 
     else: 
      pass 

    return downloaded_wordlists, downloaded_rainbow_tables 

Это работает, да, но это очень медленно, из-за размера файлов, каждый файл имеет по крайней мере 100000 строк в нем. Как я могу ускорить эту функцию, чтобы сделать ее более быстрой и удобной для пользователя?

+0

Хммм, это зависит от вашего Wi-Fi соединения. Вы почти не можете ускорить это, кроме улучшения вашего Wi-Fi. Жаль это говорить. – Qwerty

+0

@ Qwerty даже с резьбой? Я имею в виду, что это медленно, да, это будет стоить того, в конце концов, но это медленный процесс инициализации. – papasmurf

+2

Ну ... http://stackoverflow.com/a/9010299/2308683 –

ответ

1

Несколько недель назад я столкнулся с аналогичной ситуацией, когда понадобилось загрузить много огромных файлов, но все простые чистые решения Python, которые я нашел, были недостаточно хороши с точки зрения оптимизации загрузки. Так что я нашел Axel - Light командной строки скачать ускоритель для Linux и Unix

Что такое Axel?

Axel пытается ускорить процесс загрузки, используя несколько подключений для одного файла, похожие на DownThemAll и другие известные программы . Он также может использовать несколько зеркал для одной загрузки.

Используя Axel, вы получите файлы быстрее из Интернета. Итак, Axel может ускорить загрузку до 60% (примерно, согласно некоторым тестам).

Usage: axel [options] url1 [url2] [url...] 

--max-speed=x  -s x Specify maximum speed (bytes per second) 
--num-connections=x -n x Specify maximum number of connections 
--output=f  -o f Specify local output file 
--search[=x]  -S [x] Search for mirrors and download from x servers 
--header=x  -H x Add header string 
--user-agent=x  -U x Set user agent 
--no-proxy  -N Just don't use any proxy server 
--quiet   -q Leave stdout alone 
--verbose  -v More status information 
--alternate  -a Alternate progress indicator 
--help   -h This information 
--version  -V Version information 

Как axel написана на C и нет никакого расширения C для Python, так что я использовал subprocess модуль для выполнения его снаружи и отлично работает для меня.

Вы можете сделать что-то вроде этого:

cmd = ['/usr/local/bin/axel', '-n', str(n_connections), '-o', 
       "{0}".format(filename), url] 
process = subprocess.Popen(cmd,stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

Можно также проанализировать ход каждой загрузки разборе вывод на стандартный вывод.

while True: 
     line = process.stdout.readline() 
     progress = YOUR_GREAT_REGEX.match(line).groups() 
     ... 

+0

Это работает только в том случае, если хостинг-сайт поддерживает параллельные загрузки –

+0

Это правда, но может быть полезно в большинстве случаев.К сожалению, это не серебряная пуля. – GustavoIP

+0

@GustavolP Я также работаю на компьютере с Windows .. Это гениальная работа вокруг, хотя так +1 – papasmurf

0

Вы блокируете, пока вы ждете для каждой загрузки. Таким образом, общее время представляет собой сумму времени в оба конца для каждой загрузки. Ваш код, скорее всего, потратит много времени на ожидание сетевого трафика. Один из способов улучшить это - не блокировать, пока вы ждете ответа. Вы можете сделать это несколькими способами. Например, передавая каждый запрос отдельному потоку (или процессу) или используя цикл событий и сопрограммы. Прочтите информацию о потоковых и асинхронных модулях.

+0

Разрабатывайте то, что вы подразумеваете, блокируя при ожидании каждой загрузки? – papasmurf

+1

urlopen(), за которым следует read(), означает, что вы ожидаете, что соединение будет открыто, запрос будет отправлен и ответ будет получен. Этот сетевой трафик, вероятно, будет значительным временем, и большая часть времени, затрачиваемого вашим кодом, ждет сетевой трафик. Когда у вас есть много запросов, чтобы вы не хотели дожидаться ответа на первый, прежде чем вы начнете следующий. –

+0

Итак, как вы предлагаете мне это сделать? Создайте очередь потоков и просто потяните их, когда они мне понадобятся? – papasmurf

Смежные вопросы