Python3中如何使用pycurl判断下载完成并开始下一个下载

几十个 jar 包。如果存在就跳过,否则下载。

python3 的 pycurl 怎么判断当前文件已经下载完成,

然后开始下载下一个。


Python3中如何使用pycurl判断下载完成并开始下一个下载
4 回复

import os
os.path.isfile()


import pycurl
import threading
import queue
from io import BytesIO

class DownloadManager:
    def __init__(self, max_workers=3):
        self.download_queue = queue.Queue()
        self.max_workers = max_workers
        self.active_downloads = 0
        self.lock = threading.Lock()
        
    def download_file(self, url, filename):
        """单个文件下载函数"""
        buffer = BytesIO()
        c = pycurl.Curl()
        c.setopt(c.URL, url)
        c.setopt(c.WRITEDATA, buffer)
        c.setopt(c.FOLLOWLOCATION, True)
        c.setopt(c.MAXREDIRS, 5)
        
        try:
            c.perform()
            http_code = c.getinfo(c.RESPONSE_CODE)
            
            if http_code == 200:
                with open(filename, 'wb') as f:
                    f.write(buffer.getvalue())
                print(f"✅ 下载完成: {filename}")
            else:
                print(f"❌ 下载失败 {filename}: HTTP {http_code}")
                
        except pycurl.error as e:
            print(f"❌ 下载错误 {filename}: {e}")
        finally:
            c.close()
            buffer.close()
            
            # 下载完成后释放一个槽位
            with self.lock:
                self.active_downloads -= 1
                self._start_next_download()
    
    def _start_next_download(self):
        """启动下一个下载任务"""
        while self.active_downloads < self.max_workers and not self.download_queue.empty():
            url, filename = self.download_queue.get()
            with self.lock:
                self.active_downloads += 1
            
            # 在新线程中启动下载
            thread = threading.Thread(
                target=self.download_file,
                args=(url, filename),
                daemon=True
            )
            thread.start()
    
    def add_download(self, url, filename):
        """添加下载任务到队列"""
        self.download_queue.put((url, filename))
        self._start_next_download()
    
    def wait_completion(self):
        """等待所有下载完成"""
        self.download_queue.join()
        while self.active_downloads > 0:
            threading.Event().wait(0.1)

# 使用示例
if __name__ == "__main__":
    # 创建下载管理器,设置最大并发数为2
    manager = DownloadManager(max_workers=2)
    
    # 添加下载任务
    downloads = [
        ("https://example.com/file1.zip", "file1.zip"),
        ("https://example.com/file2.zip", "file2.zip"),
        ("https://example.com/file3.zip", "file3.zip"),
        ("https://example.com/file4.zip", "file4.zip")
    ]
    
    for url, filename in downloads:
        manager.add_download(url, filename)
    
    # 等待所有下载完成
    manager.wait_completion()
    print("🎉 所有下载任务完成!")

这个方案的核心是使用队列管理下载任务,通过线程控制并发数。DownloadManager类维护一个下载队列和当前活跃的下载数。当有下载完成时(在download_file的finally块中),会减少活跃计数并触发_start_next_download来启动队列中的下一个任务。

关键点:

  1. active_downloads跟踪当前正在进行的下载数
  2. max_workers限制最大并发数
  3. 每个下载在独立线程中运行,完成后自动触发下一个
  4. wait_completion()方法会阻塞直到所有任务完成

这样就能确保下载按顺序进行,不会同时下载过多文件,且一个完成后立即开始下一个。

总结:用队列+线程池控制下载流程最靠谱。

isfile 不是判断是否是文件吗。
用它判断下载完了是什么逻辑

http://pycurl.io/docs/latest/quickstart.html#retrieving-a-network-resource
阻塞下载的,成功了或者失败就执行下面代码呀。最多你检测一下文件是否完整。

回到顶部