我编写的程序必须先从网上下载一堆文件才能运行,所以我创建了一个可以下载所有文件的函数,并且"初始化&#34 ; 名为init_program
的程序,它的工作原理是它通过一对dicts
运行,它们在github上有一个gistfiles的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
这是可行的,但是它非常慢,由于文件的大小,每个文件至少有100,000行。如何加快此功能,使其更快,更友好?
答案 0 :(得分:1)
几周前,我遇到了类似的情况,需要下载许多大文件,但我发现所有简单的纯Python解决方案在下载优化方面都不够好。所以我找到了 Axel - 适用于Linux和Unix的Light命令行下载加速器
什么是Axel?
Axel尝试使用多个加速下载过程 连接一个文件,类似于DownThemAll和其他着名的 程式。它也可以使用多个镜像进行一次下载。
使用Axel,您可以更快地从Internet获取文件。所以,阿克塞尔可以 加速下载高达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语言编写的,并且没有Python的C扩展,所以我使用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)
您还可以解析每次下载解析stdout输出的进度。
while True:
line = process.stdout.readline()
progress = YOUR_GREAT_REGEX.match(line).groups()
...
答案 1 :(得分:0)
在等待每次下载时,您正在阻止。因此,总时间是每次下载的往返时间的总和。您的代码可能会花费大量时间等待网络流量。改善这种情况的一种方法是在等待每个响应时阻止。您可以通过多种方式完成此操作。例如,通过将每个请求移交给单独的线程(或进程),或者使用事件循环和协同程序。阅读线程和asyncio模块。