Python 多线程下载器:高效下载文件
Python 多线程下载器:高效下载文件/n/n本代码实现了一个简单的 Python 多线程下载器,可以有效地提高文件下载速度。/n/n### 代码/n/npython/nimport sys/nimport os/nimport math/nimport time/nimport requests/nimport urllib.request/nimport threading/nfrom tqdm import tqdm/n/n/nclass DownloadThread(threading.Thread):/n def __init__(self, url, start, end, fileobj, bar):/n threading.Thread.__init__(self)/n self.url = url/n self.start = start/n self.end = end/n self.fileobj = fileobj/n self.bar = bar/n/n def run(self):/n headers = {'Range': 'bytes=%d-%d' % (self.start, self.end)}/n response = requests.get(self.url, headers=headers, stream=True)/n for chunk in response.iter_content(chunk_size=1024):/n if not chunk:/n break/n self.fileobj.write(chunk)/n self.bar.update(len(chunk))/n/n/ndef download_file(url:str, filename:str, num_threads:int=4) -> None:/n response = requests.get(url, stream=True)/n if 'Content-Length' in response.headers:/n file_size = int(response.headers['Content-Length'])/n else:/n print('The file size is unknown, use single thread download.')/n download_single_thread(url=url, filename=filename)/n return/n/n # 判断文件大小是否为0/n if file_size == 0:/n raise ValueError('Failed to get file size, please check the download URL')/n/n with open(filename, 'wb') as file:/n with tqdm(total=file_size, unit='B', unit_scale=True,/n desc=os.path.basename(filename), ncols=80, position=0) as bar:/n/n download_time = 0/n chunk_size = 1024/n avg_speed = 0/n last_speed = 0/n while True:/n start = time.time()/n chunk = response.raw.read(chunk_size*num_threads)/n end = time.time()/n/n if not chunk:/n break/n/n used_time = end - start/n download_time += used_time/n/n speed = chunk_size*num_threads/used_time/n avg_speed = (avg_speed + speed) / 2/n/n if avg_speed > 0:/n last_speed = avg_speed/n num_threads = int(file_size / avg_speed / chunk_size) + 1/n num_threads = min(max(num_threads, 1), 32)/n/n thread_pool = []/n start = 0/n end = -1/n for i in range(num_threads):/n start = end + 1/n end = start + chunk_size - 1/n/n if i == num_threads - 1:/n end = file_size - 1/n/n thread = DownloadThread(url=url, start=start, end=end, fileobj=file, bar=bar)/n thread.setDaemon(True)/n thread_pool.append(thread)/n/n for thread in thread_pool:/n thread.start()/n/n for thread in thread_pool:/n thread.join()/n/n bar.update(chunk_size*num_threads)/n/n bar.close()/n/n return filename/n/n/ndef download_single_thread(url:str, filename:str) -> None:/n urllib.request.urlretrieve(url, filename)/n return filename/n/n/ndef download(input_str:str, filename:str, num_threads:int=4) -> None:/n try:/n if input_str.startswith('magnet:'):/n download_magnet(input_str, output_filename)/n if os.path.isdir(filename):/n output_filename = os.path.join('./Download', os.path.basename(input_str))/n else:/n output_filename = os.path.join('./Download', os.path.basename(input_str))/n if not os.path.exists('.//Download'):/n os.makedirs('.//Download')/n download_file(input_str, output_filename, num_threads)/n /n print(f'Download succeed! The file is saved as: {output_filename}')/n except Exception as e:/n print('Download failed, exception:', e)/n/n/nif __name__ == '__main__':/n if len(sys.argv) < 3:/n print('Usage: python download.py url output_file')/n sys.exit(1)/n/n url = sys.argv[1]/n filename = sys.argv[2]/n/n download(input_str=url, filename=filename, num_threads=4)/n/n/n### 使用方法/n/n1. 确保你已经安装了 requests 和 tqdm 库。可以使用以下命令安装:/nbash/npip install requests tqdm/n/n/n2. 将代码保存为 download.py 文件。/n/n3. 打开命令行窗口,并进入 download.py 文件所在的目录。/n/n4. 输入以下命令进行下载,其中 [下载链接] 替换为你要下载文件的链接,[文件名] 替换为你要保存的文件名:/nbash/npython download.py [下载链接] [文件名]/n/n/n例如,要下载 https://example.com/file.zip 文件并保存为 file.zip,可以输入以下命令:/nbash/npython download.py https://example.com/file.zip file.zip/n/n/n5. 等待下载完成即可。/n/n### 代码说明/n/n1. 代码使用了 requests 库来发送 HTTP 请求,tqdm 库来显示下载进度条。/n2. DownloadThread 类定义了一个下载线程,负责下载文件的一部分内容。/n3. download_file 函数是主下载函数,负责创建下载线程、分配下载任务并监控下载进度。/n4. download_single_thread 函数使用 urllib.request.urlretrieve 函数实现单线程下载。/n5. download 函数用于处理用户输入,并调用相应的下载函数。/n/n### 注意事项/n/n1. 下载速度会受到网络状况、服务器性能等因素的影响。/n2. 如果你要下载的文件非常大,建议使用多线程下载来提高下载速度。/n3. 如果你要下载的文件非常小,使用单线程下载可能更有效率。/n/n### 总结/n/n本代码实现了一个简单的 Python 多线程下载器,可以有效地提高文件下载速度。希望本文能帮助你更好地理解 Python 多线程编程,并应用到实际项目中。/n
原文地址: https://www.cveoy.top/t/topic/oHP4 著作权归作者所有。请勿转载和采集!