Помогите спарсить описание ролика YouTube
Пишу парсер видеороликов YouTube. Так, как в оф. API есть квоты, которые мешают нормальному парсингу, выбор пал на селениум, который я всегда обходил стороной. Смог спарсить ссылки на ролики из запроса и переходить по этим ссылкам. А вот описание парсить совсем не получается, пишет или None или List index out of range. Совсем новичок, поэтому буду рад коду или любой другой максимально понятной помощи.
import selenium
import time
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
browser = webdriver.Chrome(ChromeDriverManager().install())
browser.get("https://www.youtube.com/results?search_query=gta5")
def search():
videos = browser.find_elements_by_id("video-title")
href = videos[1].get_attribute('href')
browser.execute_script("window.open('');")
browser.switch_to.window(browser.window_handles[1])
browser.get(f"{href}")
videos = browser.find_elements_by_id("description")
text = videos[1].get_attribute('class')
for t in text:
print(t.text)
search()
Мне нужно как-то получить текст из описания.
Ответы (1 шт):
У меня получилось следующее...
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from time import sleep
info_videos = {}
request = "https://www.youtube.com/results?search_query=" + input("Enter your request: ")
scroll_pause_time = 0.5
titles_locator = "//ytd-video-renderer[@class='style-scope ytd-item-section-renderer']//a[@id='video-title']"
info_locators = [
"//h1/yt-formatted-string",
"//ytd-toggle-button-renderer/a/yt-formatted-string[@aria-label][@class='style-scope ytd-toggle-button-renderer style-text'][1]"]
btn_more_locators = [
"//div[@id='above-the-fold']//tp-yt-paper-button[@id='expand']",
"//div[@id='container']//tp-yt-paper-button[@id]/yt-formatted-string[text()='Ещё']"]
try:
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get(request)
for _ in range(2):
try:
render_section = WebDriverWait(driver, 120).until(
EC.presence_of_element_located((By.XPATH, "//div[@class='style-scope ytd-section-list-renderer'][@id='contents']/ytd-continuation-item-renderer")))
driver.execute_script("arguments[0].scrollIntoView();", render_section)
sleep(scroll_pause_time)
except Exception:
continue
url_videos = WebDriverWait(driver, 120).until(lambda d: [url.get_attribute("href") for url in d.find_elements(By.XPATH, titles_locator)])
for url in url_videos:
if "watch" not in url:
continue
driver.get(url)
# Загружаем кнопку more
list_btns_more = WebDriverWait(driver, 120).until(lambda d: False if [d.find_elements(By.XPATH, locator) for locator in btn_more_locators] == [[], []] else [d.find_elements(By.XPATH, locator) for locator in btn_more_locators])
for tuple_btns_more in list_btns_more:
for btn_more in tuple_btns_more:
btn_more.click()
# Собираем данные видеоролика и добавляем в словарь
print("\nGather info...\n")
info = WebDriverWait(driver, 120).until(lambda d: False if "" in [d.find_element(By.XPATH, locator).text for locator in info_locators] else [d.find_element(By.XPATH, locator).text for locator in info_locators])
description = [elem.text for elem in (WebDriverWait(driver, 60).until(
EC.presence_of_all_elements_located((By.XPATH, "//div[@id='description']//yt-formatted-string")))) if elem.is_displayed()][0]
info.append(description)
# Чтобы не запутался что за цифры добавил слово LIKES
info[1] = "LIKES " + info[1]
info_videos[url] = info
print("[" + url + "]\n", info)
finally:
for key, value in info_videos.items():
print(key, "|", value, "\n")
driver.close()
driver.quit()
Я сохранил все значения в словарь info_videos
"ссылка на видео":["заголовок", "кол-во лайков", "описание"]
Если захочешь можешь убрать вывод информации на экран при её сборе, я так сделал чтобы создать визуализацию процесса
Честно сказать мне кажется костыль))), можно и лучше, а так пойдет :)