Как получить все комментарии в youtube с помощью селена?

На веб-странице показано, что имеется 702 комментария.
целевой пример YouTube
введите здесь описание изображения
Я пишу функцию get_total_youtube_comments(url), многие коды скопированы из проекта на github.

проект на github

def get_total_youtube_comments(url):
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.common.exceptions import TimeoutException
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    import time
    options = webdriver.ChromeOptions()
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.add_argument("--headless")
    driver = webdriver.Chrome(options=options,executable_path='/usr/bin/chromedriver')
    wait = WebDriverWait(driver,60)
    driver.get(url)
    SCROLL_PAUSE_TIME = 2
    CYCLES = 7
    html = driver.find_element_by_tag_name('html')
    html.send_keys(Keys.PAGE_DOWN)   
    html.send_keys(Keys.PAGE_DOWN)   
    time.sleep(SCROLL_PAUSE_TIME * 3)
    for i in range(CYCLES):
        html.send_keys(Keys.END)
        time.sleep(SCROLL_PAUSE_TIME)
    comment_elems = driver.find_elements_by_xpath('//*[@id="content-text"]')
    all_comments = [elem.text for elem in comment_elems]
    return  all_comments

Попытайтесь проанализировать все комментарии на образце веб-страницы https://www.youtube.com/watch?v=N0lxfilGfak.

url='https://www.youtube.com/watch?v=N0lxfilGfak'
list = get_total_youtube_comments(url)

Он может получить несколько комментариев, только небольшую партию всех комментариев.

len(list)
60

60 намного меньше, чем 702, как получить все комментарии на YouTube с помощью селена?
@ supputuri, я могу извлечь все комментарии с помощью вашего кода.

comments_list = driver.find_elements_by_xpath("//*[@id='content-text']")
len(comments_list)
709
print(driver.find_element_by_xpath("//h2[@id='count']").text)
717 Comments
comments_list[-1].text
'mistake at 23:11 \nin NOT it should return false if x is true.'
comments_list[0].text
'Got a question on the topic? Please share it in the comment section below and our experts will answer it for you. For Edureka Python Course curriculum, Visit our Website:  Use code "YOUTUBE20" to get Flat 20% off on this training.'

Почему на странице указано 709 комментариев, а не 717?


person showkey    schedule 05.07.2020    source источник


Ответы (4)


Вы получаете ограниченное количество комментариев, так как YouTube будет загружать комментарии по мере того, как вы продолжаете прокручивать страницу вниз. К этому видео оставлено около 394 комментариев. Сначала убедитесь, что все комментарии загружены, а затем также разверните все View Replies, чтобы достичь максимального количества комментариев.

Примечание. Мне удалось получить 700 комментариев, используя приведенные ниже строки кода.

# get the last comment
lastEle = driver.find_element_by_xpath("(//*[@id='content-text'])[last()]")
# scroll to the last comment currently loaded
lastEle.location_once_scrolled_into_view
# wait until the comments loading is done
WebDriverWait(driver,30).until(EC.invisibility_of_element((By.CSS_SELECTOR,"div.active.style-scope.paper-spinner")))

# load all comments
while lastEle != driver.find_element_by_xpath("(//*[@id='content-text'])[last()]"):
    lastEle = driver.find_element_by_xpath("(//*[@id='content-text'])[last()]")
    driver.find_element_by_xpath("(//*[@id='content-text'])[last()]").location_once_scrolled_into_view
    time.sleep(2)
    WebDriverWait(driver,30).until(EC.invisibility_of_element((By.CSS_SELECTOR,"div.active.style-scope.paper-spinner")))

# open all replies
for reply in driver.find_elements_by_xpath("//*[@id='replies']//paper-button[@class='style-scope ytd-button-renderer'][contains(.,'View')]"):
    reply.location_once_scrolled_into_view
    driver.execute_script("arguments[0].click()",reply)
time.sleep(5)
WebDriverWait(driver, 30).until(
        EC.invisibility_of_element((By.CSS_SELECTOR, "div.active.style-scope.paper-spinner")))
# print the total number of comments
print(len(driver.find_elements_by_xpath("//*[@id='content-text']")))
person supputuri    schedule 08.07.2020
comment
Почти готово, почему количество комментариев, извлеченных с помощью вашего кода, составляет 709, а число, указанное на веб-странице в начале списка комментариев, - 717? Пожалуйста, посмотрите мой обновленный пост. - person showkey; 11.07.2020

Есть пара вещей:

  • WebElement внутри веб-сайт https://www.youtube.com/ являются динамическими. Так что комментарии отображаются динамически.
  • На веб-странице https://www.youtube.com/watch?v=N0lxfilGfak комментарии не отображаются, если пользователь не прокручивает следующий элемент в области просмотра .

edureka

  • Комментарии находятся в:

    <!--css-build:shady-->
    

    Что применимо, используется Polymer CSS Builder, применяется прокладка CSS Mixin от Polymer и область действия ShadyDOM. Таким образом, некоторая работа во время выполнения все еще выполняется для преобразования селекторов CSS с настройками по умолчанию.


Учитывая вышеупомянутые факторы, вот решение для получения всех комментариев:

Блок кода:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException, ElementClickInterceptedException, WebDriverException
import time

options = webdriver.ChromeOptions() 
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
driver.get('https://www.youtube.com/watch?v=N0lxfilGfak')
driver.execute_script("return scrollBy(0, 400);")
subscribe = WebDriverWait(driver, 60).until(EC.visibility_of_element_located((By.XPATH, "//yt-formatted-string[text()='Subscribe']")))
driver.execute_script("arguments[0].scrollIntoView(true);",subscribe)
comments = []
my_length = len(WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//yt-formatted-string[@class='style-scope ytd-comment-renderer' and @id='content-text'][@slot='content']"))))
while True:
    try:
        driver.execute_script("window.scrollBy(0,800)")
        time.sleep(5)
        comments.append([my_elem.text for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//yt-formatted-string[@class='style-scope ytd-comment-renderer' and @id='content-text'][@slot='content']")))])
    except TimeoutException:
        driver.quit()
        break
print(comment)
person DebanjanB    schedule 09.07.2020
comment
На извлечение комментариев уходит больше времени, чем на суппутури. - person showkey; 11.07.2020
comment
Что ж :) Я согласен, для этого и предназначен Selenium, чтобы высмеивать действия пользователя, согласны? Вы должны увидеть, как Selenium имитирует прокрутка действий пользователя до конца. Однако завтра утром я постараюсь улучшить ответ, если возможно. - person DebanjanB; 11.07.2020
comment
Пожалуйста, взгляните на мою обновленную публикацию, там ожидает новая проблема. - person showkey; 11.07.2020
comment
@showkey Можете ли вы проверить обновленный код сейчас, вы не должны столкнуться с предыдущей ошибкой NoSuchElement. - person DebanjanB; 12.07.2020

Если вам не нужно использовать Selenium, я бы порекомендовал вам взглянуть на google / youtube api.

https://developers.google.com/youtube/v3/getting-started

Пример :

person Leander Mihm    schedule 08.07.2020


Я не знаком с python, но я расскажу вам шаги, которые я бы сделал, чтобы получить все комментарии. Прежде всего, если ваш код, я думаю, основная проблема связана с

CYCLES = 7

В соответствии с этим вы будете прокручивать по 2 секунды 7 раз. Поскольку вы успешно получили 60 комментариев, устранение вышеуказанного условия решит вашу проблему.

Я предполагаю, что у вас нет проблем с поиском элементов на веб-сайте с помощью локаторов.

  1. Вам нужно, чтобы общее количество комментариев учитывалось для переменной как int. (в вашем случае, допустим, это КОММЕНТАРИИ = 715)

  2. Определите другую переменную с именем VISIBLECOUNTS = 0

  3. Используйте цикл while для прокрутки, если КОММЕНТАРИИ ›VISIBLECOUNTS

  4. Код может выглядеть так (очень извините, если есть проблемы с синтаксисом)

    // python - selenium command to get all comments counts.
    COMMENTS = 715
    (715 is just a sample value, it will change upon the total comments count)
    VISIBLECOUNTE = 0 
    SCROLL_PAUSE_TIME = 2
    
    while VISIBLECOUNTS  < COMMENTS :
    html.send_keys(Keys.END)
    time.sleep(SCROLL_PAUSE_TIME)
    VISIBLECOUNTS = len(driver.find_elements_by_xpath('//ytm-comment-thread-renderer'))
    

    При этом вы будете прокручивать страницу вниз, пока не увидите КОММЕНТАРИИ = ВИДИМЫЕ ЗНАЧЕНИЯ. Затем вы можете получить все комментарии, поскольку все они имеют одни и те же атрибуты элементов, такие как ytm-comment-thread-renderer.

    Поскольку я не знаком с python, я добавлю команду для подсчета комментариев из js. вы можете попробовать это в своем браузере и преобразовать в свою команду python

Запустите в консоли следующие запросы и проверьте.

To get total comments count
var comments = document.querySelector(".comment-section-header-text").innerText.split(" ")
//We can get the text value "Comments • 715" and split by spaces and get the last value

Number(comments[comments.length -1])
//Then convirt string "715" to int, you just need to do these in python - selenium
To get active comments count
$x("//ytm-comment-thread-renderer").length

Примечание: если трудно извлечь значения, вы все равно можете использовать исполнитель selenium js и выполнять прокрутку с помощью js, пока не будут видны все комментарии. Но я думаю, это не сложно сделать на питоне, поскольку логика такая же.

Мне очень жаль, что я не могу добавить решение на Python. Но надеюсь, что это помогло. ваше здоровье.

person Muditha Perera    schedule 09.07.2020