Printing Youtube video title in Selenium

Viewed 322

I'm trying to print the title of a YouTube video in Selenium. I tried it 3 different ways and only one way worked. so I just want to know why the other ways didn't work.

My first try:

videoTitle = driver.find_element_by_css_selector("yt-formatted-string.style-scope ytd-video-primary-info-renderer")
print(videoTitle)

This didn't work and the error is:

  File "C:\Users\forre\IdeaProjects\PythonNotes\Packages\Selenium\Web_Scraping.py", line 21, in <module>
    videoTitle = driver.find_element_by_xpath("/html/body/ytd-app/div/ytd-page-manager/ytd-watch-flexy/div[5]/div[1]/div/div[8]/div[2]/ytd-video-primary-info-renderer/div/h1/yt-formatted-string")
  File "C:\Users\forre\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 520, in find_element_by_xpath
    return self.find_element(by=By.XPATH, value=xpath)
  File "C:\Users\forre\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 1244, in find_element
    return self.execute(Command.FIND_ELEMENT, {
  File "C:\Users\forre\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 424, in execute
    self.error_handler.check_response(response)
  File "C:\Users\forre\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 247, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/ytd-app/div/ytd-page-manager/ytd-watch-flexy/div[5]/div[1]/div/div[8]/div[2]/ytd-video-primary-info-renderer/div/h1/yt-formatted-string"}
  (Session info: chrome=96.0.4664.110)
Stacktrace:
Backtrace:
    Ordinal0 [0x002C6903+2517251]
    Ordinal0 [0x0025F8E1+2095329]
    Ordinal0 [0x00162848+1058888]
    Ordinal0 [0x0018D448+1233992]
    Ordinal0 [0x0018D63B+1234491]
    Ordinal0 [0x001B7812+1406994]
    Ordinal0 [0x001A650A+1336586]
    Ordinal0 [0x001B5BBF+1399743]
    Ordinal0 [0x001A639B+1336219]
    Ordinal0 [0x001827A7+1189799]
    Ordinal0 [0x00183609+1193481]
    GetHandleVerifier [0x00455904+1577972]
    GetHandleVerifier [0x00500B97+2279047]
    GetHandleVerifier [0x00356D09+534521]
    GetHandleVerifier [0x00355DB9+530601]
    Ordinal0 [0x00264FF9+2117625]
    Ordinal0 [0x002698A8+2136232]
    Ordinal0 [0x002699E2+2136546]
    Ordinal0 [0x00273541+2176321]
    BaseThreadInitThunk [0x76136739+25]
    RtlGetFullPathName_UEx [0x77D78AFF+1215]
    RtlGetFullPathName_UEx [0x77D78ACD+1165]
    (No symbol) [0x00000000]


Process finished with exit code 1

My second try:

videoTitle = driver.find_element_by_xpath("/html/body/ytd-app/div/ytd-page-manager/ytd-watch-flexy/div[5]/div[1]/div/div[8]/div[2]/ytd-video-primary-info-renderer/div/h1/yt-formatted-string")
print(videoTitle)

This also didn't work and I got the same error.

1 Answers

Your first attempt with

videoTitle = driver.find_element_by_css_selector("yt-formatted-string.style-scope ytd-video-primary-info-renderer")

Has 3 problems:

  1. yt-formatted-string.style-scope ytd-video-primary-info-renderer is not a valid CSS Selector for that element. The 2 strings style-scope and ytd-video-primary-info-renderer are the 2 class attribute values. To make the above expression valid you have to put a dot . before each of them since in CSS Selector a dot . before a value indicates that this is a class name.
  2. So, yt-formatted-string.style-scope.ytd-video-primary-info-renderer will be a correct CSS Selector, however it will match 3 elements on that page while you want to access the second one.
    You can do this with find_elements_by_css_selector method, accessing the second element from the list.
  3. You have to extract the text from the web element
    So, to get the YouTube video title with the first approach your code should be:
videoTitle = driver.find_elements_by_css_selector("yt-formatted-string.style-scope ytd-video-primary-info-renderer")[1].text

As about /html/body/ytd-app/div/ytd-page-manager/ytd-watch-flexy/div[5]/div[1]/div/div[8]/div[2]/ytd-video-primary-info-renderer/div/h1/yt-formatted-string - you are trying to use an absolute XPath expression. This kind of locator is extremely fragile. I tried to use it and couldn't match nothing with this locator.
You should learn how to create correct XPath locators.
For example this will be correct XPath locator here:

"//h1//*[@class='style-scope ytd-video-primary-info-renderer']"

So this will work:

videoTitle = driver.find_element_by_xpath("//h1//*[@class='style-scope ytd-video-primary-info-renderer']").text
print(videoTitle)
Related