如何使用Selenium WebDriver读取shadowRoot数据爬取福克斯新闻评论
Selenium 读取 shadowRoot 内福克斯新闻评论的可行方案
原有代码问题排查
- 未设置等待逻辑:页面加载完成后评论组件是异步初始化的,刚执行
driver.get(url)就查询元素会找不到未渲染的节点 - 未触发评论加载:福克斯新闻的评论组件需要滚动到可视区域才会触发内部内容加载,直接查询shadowRoot会返回空
- 重复调用
driver.get(url)无意义,反而会重置页面状态
完整可运行代码(Selenium 4.0+ 推荐写法)
from selenium import webdriver from selenium.webdriver.firefox.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.action_chains import ActionChains options = Options() options.binary_location = r'C:\Program Files\Mozilla Firefox\firefox.exe' # 新版本Selenium建议用Service配置geckodriver路径,此处兼容旧写法 driver = webdriver.Firefox(executable_path=r'C:\Users\******\Downloads\geckodriver.exe', options=options) driver.maximize_window() url = "https://www.foxnews.com/sports/nfl-great-frank-gore-says-hall-of-famer-numbers-speak-themselves" driver.get(url) wait = WebDriverWait(driver, 20) # 最长等待20秒,可根据网络情况调整 try: # 等待评论容器节点加载完成 comment_container = wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, 'div.article-comments')) ) # 滚动到评论容器位置,触发组件渲染 ActionChains(driver).scroll_to_element(comment_container).perform() # 获取shadowRoot对象(Selenium 4.0+ 原生支持) shadow_root = comment_container.shadow_root # 等待shadowRoot内的评论列表加载完成 comment_list = wait.until( lambda d: shadow_root.find_element(By.CSS_SELECTOR, 'ul.spcv_messages-list') ) # 输出评论内容 print(comment_list.text) finally: # 按需调整是否自动关闭浏览器 driver.quit()
低版本Selenium兼容写法(通过JS直接读取)
如果使用的Selenium版本低于4.0,不支持原生shadow_root属性,可以替换上述shadowRoot读取逻辑为以下代码:
item = driver.execute_script(""" const container = document.querySelector('div.article-comments'); if(!container || !container.shadowRoot) return null; return container.shadowRoot.querySelector('ul.spcv_messages-list'); """) if item: print(item.text)
注意事项
- 评论列表为分页加载,如需爬取全部评论,需要额外模拟滚动到评论列表底部触发下一页加载的逻辑
- 可根据实际网络环境调整最长等待时长,避免超时报错
内容的提问来源于stack exchange,提问作者hemanth sai
相关产品推荐
相关产品推荐

