#python-3.x #beautifulsoup #python-asyncio
#python-3.x #beautifulsoup #python-asyncio
Вопрос:
Я думаю, что ошибка возникает из-за того, что 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)
не сортируя их, потому что не уверен, как проверить, является ли это фактической страницей исполнителя, все это преобразование предназначено для захвата области html, где находится результат json — может очень легко сломаться
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"))
Как мне получить фактический контент из запроса? Вместо объекта сопрограммы?
Комментарии:
1. Вероятно, вам не хватает
await
, напримерpage = await page.read()
или чего-то подобного. Кроме того, вы, вероятно, захотите использоватьasync with
, чтобы правильно закрыть запрос, как только закончите чтение.2. @user4815162342 Я использовал page.read вместо page.content, и это сработало! Однако теперь другие проблемы.
Ответ №1:
Просто используйте your_file_object.file.read()
вместо your_file_object.content
.
Итак, в вашем случае это должно быть page.file.read()
.
Если вы используете flask, это будет your_file_object.read()
.
Если вы используете fastapi, это будет your_file_object.file.raed()
.
В моем случае это работает.