如何在并行下载文件中正确使用“Pool”?

Posted

技术标签:

【中文标题】如何在并行下载文件中正确使用“Pool”?【英文标题】:How to right use "Pool" in parallel downloading files? 【发布时间】:2021-12-31 09:23:18 【问题描述】:

我想从 youtube 使用并行下载视频,但我的代码以异常“PicklingError”结尾。你能帮人写代码吗,应该怎么做,拜托。

另一个固定的变体:

import sys
#from pathos.multiprocessing import ProcessingPool as Pool
from multiprocessing import Pool
from pytube import YouTube
from youtubeMultiDownloader import UiMainWindow
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog


class YouTubeInstance:
    def __init__(self, path):
        self.youtube = YouTube
        self.path = path
        #self.ui_obj = ui_obj

    def download_file(self, url):
        self.youtube(url).streams.get_highest_resolution().download(self.path)
        #self.ui.ui.youtube_outputs.setText(f'Video \'self.youtube.title\' has been downloaded successfully!')


class YouTubeMultiDownloader(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.pool = Pool
        self.ui = UiMainWindow()
        self.ui.setup_ui(self)
        self.path_to_dir = None
        self.urls = None

    def _get_urls_from_form(self):
        self.urls = self.ui.youtube_urls.toPlainText().split('\n')
        return len(self.urls)

    def choose_directory(self):
        self.path_to_dir = str(QFileDialog.getExistingDirectory(self, "Select Directory"))

    def run_multi_downloads(self):
        youtube = YouTubeInstance(self.path_to_dir)
        self.pool(self._get_urls_from_form()).map(youtube.download_file, self.urls)


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    application = YouTubeMultiDownloader()
    application.show()
    sys.exit(app.exec_())

更新:

我的用户界面 :)

错误 1 ​​已修复:

错误 2 已修复:

错误 3 实际:

【问题讨论】:

您好,请完整添加错误信息和发生错误的行。 @Hamed_gibago 添加 因为您试图并行化一个实例方法,所以必须对整个对象进行序列化(腌制)。这通常是有问题的。我会重写这个,所以 download_file 是一个独立的函数,没有奇怪的范围,可以很容易地序列化。 @CJR 我重写了我的代码,我得到一个新的错误,不知道它是什么。在帖子屏幕中并添加了新代码。 【参考方案1】:

你用错了方向。查看multiprocessing 模块文档。正如它所说,调用Pool 方法是为了同时(并行)运行同一函数的多个实例。所以调用Pool方法你想要多少个数字,同时你的方法没有任何参数,调用它不带任何参数:

with Pool(5) as p:
    print(p.map(YouTubeMultiDownloader))

它创建 5 个并行实例。您可以更改代码以优化您的错误。

【讨论】:

我重写了我的代码,我得到一个新的错误,不知道它是什么。在帖子屏幕中并添加了新代码。 我认为您的“youtubevideodownliader”函数中的某些对象是 null 或 None 类型。在方法的第一行放一个断点并跟踪它。还要记住将池参数设置为1,这样你可以更容易地跟踪。 是的,我找到并修复了,但我得到一个新错误,天哪 :) 将在帖子中添加。 认为我需要更多收集有关 urllib 错误的信息,我想我知道出了什么问题。 祝你好运。你的用户界面很有趣???

以上是关于如何在并行下载文件中正确使用“Pool”?的主要内容,如果未能解决你的问题,请参考以下文章

应用程序无法启动,并行配置不正确的解决方法

使用 Python 并行下载多个 GCS 文件(到内存中)

并行获取文件

在 Jupyter Windows 上使用 pool 并行读取多个文件需要很长时间:

如何在 Python 中从 url 下载文件 [重复]

如何在GitHub正确地使用 Curl 下载文件?