如何用Python多进程高效使用pytube加速下载及异步实现疑问
解决方案
一、优化多进程任务分配(无需手动拆分函数)
你的6核CPU可以用进程池自动分配12个下载任务,不用手动写多个拆分函数。推荐用concurrent.futures.ProcessPoolExecutor,它会自动把任务分发到进程池里,每个进程处理等量的任务。
示例代码:
import pytube from concurrent.futures import ProcessPoolExecutor def download_audio(video_url): yt = pytube.YouTube(video_url) yt.streams.get_by_itag(251).download(output_path=r'C:\Users\Anderson\OneDrive\Desktop\Vids') if __name__ == '__main__': playlist = pytube.Playlist(youtube_playlist_link) # 6核对应进程数设为6,自动分配12个任务(每个进程处理2个) with ProcessPoolExecutor(max_workers=6) as executor: executor.map(download_audio, playlist.video_urls)
这样不用手动拆分任务,进程池会自动把playlist.video_urls里的12个URL均匀分给6个进程,每个进程处理2个下载任务,效率和手动拆分一致,但代码简洁很多。
二、关于你的异步代码及异步编程的要求
- 你的异步代码不正确:pytube的
download方法是同步阻塞的,不是异步协程,所以await关键字对它无效。执行这段代码时,依然是逐个同步下载,不会有异步并发的效果。 - 使用async确实要求调用的核心方法支持异步:如果第三方库没有提供异步API(比如返回
async def定义的协程对象),单纯用await包裹同步方法不会实现异步并发,反而会因为事件循环被同步任务阻塞,和同步代码没区别。
如果想基于pytube做异步处理,只能把同步的下载方法包装到线程池/进程池里,通过asyncio.run_in_executor来调用,但本质上还是用多线程/多进程实现并发,和直接用进程池的效果差不多,没必要绕一层异步。
内容的提问来源于stack exchange,提问作者Beautiful Blobfish
相关产品推荐
相关产品推荐

