Selenium中find_element().get_attribute()返回None的问题
Selenium获取YouTube视频链接返回None的问题分析与解决
问题场景
使用Selenium爬取YouTube频道(https://www.youtube.com/@PythonToday/videos)的视频链接时,调用find_element().get_attribute('href')全部返回None,但改用BeautifulSoup解析同一页面的源码却能正常获取链接。尝试添加显式等待和XPATH定位后,问题依然存在。
原Selenium代码:
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By import time s = Service('C:\\Users\\user\\Desktop\\chromedriver-win64\\chromedriver.exe') link = 'https://www.youtube.com/@PythonToday/videos' browser = webdriver.Chrome(service=s) browser.maximize_window() browser.implicitly_wait(40) browser.get(link) time.sleep(10) all_elements = browser.find_elements(By.ID, 'dismissible') for item in all_elements: jj = item.find_element(By.ID, 'thumbnail') vv = jj.get_attribute('href') print(vv)
问题原因分析
- 相对路径定位错误:使用XPATH全局搜索
//*[@id="thumbnail"]时,会从整个文档根节点查找元素,而非当前dismissible元素的子节点,导致获取的元素并非目标视频的链接元素。 - 动态属性获取方式差异:YouTube的视频链接
href是通过JavaScript动态注入到DOM中的,get_attribute('href')获取的是HTML源码中的初始属性值(可能为None),而get_property('href')获取的是DOM对象的实时属性值,更适配动态生成的属性。 - 等待条件不精准:仅等待元素“存在”(
presence_of_element_located)不足以确保元素的属性已被JavaScript赋值,需要等待元素“可见”且属性加载完成。
解决方法与修正代码
针对上述问题,对代码进行以下修正:
- 使用相对XPATH(前缀加
.)在当前dismissible元素下查找目标链接; - 用
get_property('href')替代get_attribute('href')获取动态生成的链接; - 等待元素“可见”而非仅“存在”,确保属性已加载完成。
修正后的代码:
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC s = Service('C:\\Users\\user\\Desktop\\chromedriver-win64\\chromedriver.exe') link = 'https://www.youtube.com/@PythonToday/videos' browser = webdriver.Chrome(service=s) browser.maximize_window() try: browser.get(link) # 等待视频列表中的链接元素全部可见 WebDriverWait(browser, 20).until( EC.visibility_of_all_elements_located((By.XPATH, '//div[@id="dismissible"]//a[@id="thumbnail"]')) ) all_elements = browser.find_elements(By.XPATH, '//div[@id="dismissible"]') for item in all_elements: # 相对路径查找当前视频项中的链接元素 thumbnail_link = WebDriverWait(item, 10).until( EC.visibility_of_element_located((By.XPATH, './/a[@id="thumbnail"]')) ) # 获取DOM实时属性中的链接 video_url = thumbnail_link.get_property('href') if video_url: print(video_url) finally: # 确保浏览器正常关闭 browser.quit()
补充说明
YouTube的页面结构会频繁更新,依赖ID定位可能存在稳定性问题。如果后续再次出现类似问题,可尝试通过更稳定的属性组合定位元素(例如结合data-id属性或视频标题的父节点关系)。
内容的提问来源于stack exchange,提问作者mr.Jenkins
相关产品推荐
相关产品推荐

