首页 > 解决方案 > TypeError:需要一个类似字节的对象,而不是“协程”

问题描述

我认为发生错误是因为 bs 正在从 page.content 获取协程,我不确定如何修复它。任何帮助表示赞赏。

这是程序中的所有相关代码:

async def find_song_on_youtube(song_name, session):
    # TODO: Make this fx async
    song_name_query = song_name.replace(" ", "+")
    page = await session.request(method='GET', url=
    f"https://www.youtube.com/results?search_query={song_name_query}")
    page = page.content
    return sort_return_final_result(page, song_name)

没有对这些进行排序,因为不确定如何检查它是否是实际的艺术家页面,所有这些转换都是为了获取结果 json 所在的 html 区域 - 可能很容易中断

def sort_return_final_result(page, song_name):
    page = bs(page, 'html5lib')
    page = str(page.find_all("script")[-3]).split("=", 1)[1].strip()[:-1].split("\n")[0][:-1]
    page = json.loads(page)
    # drilling down to where the video contents are
    full_page = (page["contents"]["twoColumnSearchResultsRenderer"]["primaryContents"]
    ["sectionListRenderer"]["contents"][0]["itemSectionRenderer"]["contents"])
    # sometimes the video is not in the first position, this should drill down until it finds
    # the first video item, should be in the videoRenderer key
    first_two_results = []
    for item in full_page:
        if len(first_two_results) >= 2:
            break
        try:
            page = item["videoRenderer"]
            first_two_results.append(parse_video_info(page))
        except KeyError:
            continue

首先按观看次数排序,然后获取官方艺术家观看次数最高的视频(如果有)

    first_two_results.sort(key=itemgetter("Views"), reverse=True)
    first_two_results.sort(key=itemgetter("Official Artist"), reverse=True)
    final_result = {}
    for item in first_two_results:
        if fuzz.partial_ratio(item["Name"], song_name.split('+')[1]) > 50:
            final_result = item
            break
    print(final_result)
    return final_result


def parse_video_info(page):
    # name of video
    name = page["title"]["runs"][0]["text"]
    # url of video
    url = page["navigationEndpoint"]["commandMetadata"]["webCommandMetadata"]["url"]
    url = f'https://youtube.com{url}'
    # views
    views = int(page["viewCountText"]["simpleText"].split()[0].replace(",", ""))
    # official artist check
    try:
        official_artist = page["ownerBadges"][0]["metadataBadgeRenderer"]["tooltip"]
        if official_artist != "Official Artist Channel":
            raise KeyError
        official_artist = True
    except KeyError:
        official_artist = False
    return {
        "Name": name,  # encoding issues here might be a problem later
        "Url": url,
        "Views": views,
        "Official Artist": official_artist
    }


async def get_song_urls(playlist_or_album, resource_id):
    song_list = []  # to get rid of pycharm error
    rsrc_name = ""
    if playlist_or_album == "Playlist":  # rsrc id could be playlist or album id
        song_list = return_songs_from_playlist(resource_id)
        rsrc_name = spotfy_obj.playlist(resource_id)['name']
    elif playlist_or_album == "Album":
        song_list = return_songs_from_album(resource_id)
        rsrc = spotfy_obj.album(resource_id)
        rsrc_name = rsrc['name']
        rsrc_name += f" - by {rsrc['artists'][0]['name']}"
    print("Collected Songs from Playlist")
    t1 = time()
    async with ClientSession() as session:
        playlist = await asyncio.gather(*[find_song_on_youtube(song, session)
                                          for song in song_list])
    t2 = time()
    print(t2 - t1)
    dump_playlist_to_db(playlist, rsrc_name)
    print(playlist)


asyncio.run(get_song_urls("Album", "6a4HHZe13SySfC50BGy8Hm"))

如何从请求中获取实际内容?而不是协程对象?

标签: python-3.xbeautifulsouppython-asyncio

解决方案


推荐阅读