卡在 pytube 上

Stuck with pytube

哦,我的 python 伙计们,请帮助我。 我的一个 python 项目突然无故停止工作。 我正在使用 pytube 模块,当我尝试 运行 代码时出现此错误:

Traceback (most recent call last):
File "C:\Users\giova\AppData\Local\Programs\Python\Python39\lib\site-packages\pytube\contrib\search.py", line 94, in fetch_and_parse
    sections = raw_results['contents']['twoColumnSearchResultsRenderer'][
KeyError: 'twoColumnSearchResultsRenderer'                                                                             fetch_and_parse

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\giova\OneDrive\Desktop\Coding\Python\youtubeapp.py", line 38, in <module>
    videoSearch()
  File "C:\Users\giova\OneDrive\Desktop\Coding\Python\youtubeapp.py", line 21, in videoSearch
    availableResults = len(vid.results)
  File "C:\Users\giova\AppData\Local\Programs\Python\Python39\lib\site-packages\pytube\contrib\search.py", line 62, in results
    videos, continuation = self.fetch_and_parse()                                                                      results
  File "C:\Users\giova\AppData\Local\Programs\Python\Python39\lib\site-packages\pytube\contrib\search.py", line 97, in fetch_and_parse                                                                                                       fetch_and_parse
    sections = raw_results['onResponseReceivedCommands'][0][
KeyError: 'onResponseReceivedCommands'

这甚至不是我遇到的唯一错误,有时我会遇到“http 错误 410:消失”之类的错误。我大约两周没有更改代码(它在两周前工作)并且它停止工作了。我不知道我的代码发生了什么。

这是完整代码:

from pytube import Search, YouTube

print("================================\n What do you want to do?: ")

availableChoose = [
    '1 Search videos', 
    '...', 
    '================================'
]

for choose in availableChoose:
    print(choose)

userChoose = input()

userChoose = userChoose.lower()

def videoSearch():
    userSearch = input("Enter the title of the video you want to search: ")
    vid = Search(userSearch)
    availableResults = len(vid.results)
    strAvailableResults = str(availableResults)
    print("The available results are " + strAvailableResults)
    vidResultsList = vid.results
    vidResultsList = str(vidResultsList)
    vidResultsList = vidResultsList.replace("<pytube.__main__.YouTube object: videoId=", "")
    vidResultsList = vidResultsList.replace(">", "")
    vidResultsList = vidResultsList.replace("[", "")
    vidResultsList = vidResultsList.replace("]", "")
    vidResultsList = vidResultsList.replace(" ", "")
    vidResultsList = vidResultsList.split(',')
    for vidResultsObject in vidResultsList:
        vidLink = ("https://www.youtube.com/watch?v=" + vidResultsObject)
        vidTempObject = YouTube(vidLink)
        print(vidTempObject.title + " - " + vidLink)
        
if(userChoose == "search" or userChoose == "search video" or userChoose == "search videos" or userChoose == "1"):
    videoSearch()

pytube 的 11.0.0 API 文档列出了 Search.fetch_and_parse() 方法。

相应的source-code表明它内部处理了onResponseReceivedCommands的KeyError:

 # Initial result is handled by try block, continuations by except block
        try:
            sections = raw_results['contents']['twoColumnSearchResultsRenderer'][
                'primaryContents']['sectionListRenderer']['contents']
        except KeyError:
            sections = raw_results['onResponseReceivedCommands'][0][
                'appendContinuationItemsAction']['continuationItems']

此方法是内部方法,供您的 vid.results 调用使用。

可能是 Youtube API 的响应发生了变化,您的 pytube 版本不再适用。

错误已提交

参见 pytube issue #1082 and issue #1106

同时使用另一个分支

tfdahlin's fork has a bugfixed version。它已经被提议作为项目的 Pull-Request:

  • PR #1090,2021-08-13 开业(目前正在等待审批)。

我也在努力绕过 pytube 搜索模块提供的搜索结果。由于搜索结果看起来像对象,我在想(懒惰地)我无法将对象列表转换为字符串。

按如下方式修改函数后,结果将打印为 youtube 链接。 '''

def videoSearch(search_list): #provide the search.results list as input
    for result in search_list: #Begin video id extraction
        result = str(result)
        temp = result.replace("<pytube.__main__.YouTube object: videoId=", "")
        temp = temp.split(',')[0] #get the correct video id
        vidLink = ("https://www.youtube.com/watch?v=" + temp)
        print(vidLink)

''' 试试吧。