为什么YoutubeDL只提取播放列表的第一个索引?

时间:2016-08-07 17:52:07

标签: python youtube-dl

我正在做一个与播放列表相关的项目,我创建了一个继承自YoutubeDL的类。

class Playlist(youtube_dl.YoutubeDL):
    info = {}

    """
    Base class for any playlist. Inherits from youtube_dl.YoutubeDL and overrides some methods to make sure that the
    link is an actual playlist and implements some cool stuff to make playlist loading easier.
    :var info: the stored information from the extract_info() method
    :type info: dict
    """

    def extract_info(self, url, download=False, ie_key=None, extra_info=None, process=True, force_generic_extractor=False):
        """
        Loads the playlist info and make sures the link is a playlist

        :param url: the link with the info to be loaded
        :param download: will it download?
        :param ie_key: see youtube_dl's doc
        :param extra_info: see youtube_dl's doc
        :param process: see youtube_dl's doc
        :param force_generic_extractor: see youtube_dl's doc
        :return: extract_info(...)["entries"] = self.info
        :rtype: list
        """
        info = super(Playlist, self).extract_info(url, download, ie_key, extra_info, process, force_generic_extractor)


        if "_type" not in info:
            raise BaseException("\"_type\" not in \"info\"!\n" + info.__str__())
        if info["_type"] != "playlist":
            raise NotPlaylistError("The url %s does not appear to be a playlist" % url)

        self.info = info["entries"]

        return self.info

    def download(self, url_list=list()):
        """
        The inherited download method - now can be used without parameters. If no url_list specified, uses self.info
        :param url_list: the url list to be downloaded
        :return: nothing
        :rtype: None
        """

        super(Playlist, self).download(url_list if url_list else self.info)

所以我只是添加了一个Playlist().extract_info(my_url)的播放列表。但它引发了一个由KeyError键引起的"_type"。因此,我玩了一些代码,我发现代码只下载了整个播放列表的第一个索引(此处发布的实际代码已经通过引发BaseError来处理)。为什么会这样?

1 个答案:

答案 0 :(得分:0)

首先,您应该查看您正在查看的the specification of the info。例如,缺少_type等同于_type 'video'。因此,正确检查信息是一个播放列表只是

if info.get('_type', 'video') != 'playlist': ..

当有人在没有参数的情况下调用download时,你的程序也会中断或做随机的事情。 YoutubeDL.download需要第一个参数(名为url_list)的网址列表。

如果之前未调用extract_info,则会调用YoutubeDL.download({})。这当前有效,但{}不是列表,因此在概念上是错误的格式。但幸运的是,这将无所作为。

但是,如果之前已调用过extract_info,并且您已建议youtube-dl 提取详细信息(例如,您为您的实例激活了listformats选项(YoutubeDL),然后self.info将是一个信息列表,而不是一个URL列表。

如果之前使用默认选项调用extract_info,则youtube-dl将递归在播放列表的每个元素上调用extract_info。在每次调用时,您都会用条目覆盖self.info(幸运的是,据我所知,播放列表会胜出,但这是一个令人难以置信的脆弱代码)。但是,as documented,每个项目都是字典,而不是URL。可能,你已经获得了一个中间设定值。

子类化也可能不必要地复杂化,特别是对于Python初学者。使用easier and more flexible可能composition

最后,请注意,在目前的描述中,您可能是XY problem的受害者。从根本上说,youtube-dl非常相似地处理一个项目和一个视频的播放列表,因此区分这两个项目并不是很有意义。