使用Python Selenium无法定位Yahoo News评论元素的求助
用Selenium爬取Yahoo News评论无法定位评论文本元素
问题背景
已成功用Selenium点击Yahoo News文章的评论按钮打开评论区,但无法定位到评论文本对应的元素,报错NoSuchElementException。
现有代码
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager test = "https://www.yahoo.com/news/cdc-advisers-recommend-spring-covid-215003196.html" # 打开评论区 driver = webdriver.Chrome() driver.get(test) comment_button = driver.find_element(By.XPATH, '//a[@class="link caas-button noborder caas-tooltip flickrComment caas-comment top"]') comment_button.click()
目标评论文本的HTML结构(精简版)
<div class="components-MessageContent-index__messageEntitiesWrapper"> <div class="components-MessageContent-components-MessageEntities-MessageEntities__message-entities components-MessageContent-components-MessageEntities-MessageEntities__is-column"> <span class="Typography__text--11-4-15 Typography__t4--11-4-15 Typography__l6--11-4-15"> <div data-spot-im-class="message-text"> <p>...</p> </div> </span> </div> </div>
已尝试的定位方式(均失败)
# 1 driver.find_element(By.XPATH, '//div[@class="components-MessageContent-index__messageEntitiesWrapper"]') # 2 driver.find_element(By.XPATH, '//div[@class="components-MessageContent-components-MessageEntities-MessageEntities__message-entities components-MessageContent-components-MessageEntities-MessageEntities__is-column"]') # 3 driver.find_element(By.XPATH, '//span[@class="Typography__text--11-4-15 Typography__t4--11-4-15 Typography__l6--11-4-15"]') # 4 driver.find_element(By.XPATH, '//div[@data-spot-im-class="message-text"]')
另外还尝试了driver.find_elements(By.XPATH, '')、driver.find_element(By.CLASS_NAME, '')等方法,同样无法找到元素。
疑问:是XPath语法错误、需要其他定位方式,还是该网站评论区无法通过Selenium爬取?
解决方案
1. 切换到评论区所在的iframe
Yahoo News评论区由第三方插件提供,大概率嵌套在<iframe>标签内。Selenium默认只能操作主文档元素,需先切换到iframe上下文:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 点击评论按钮后,等待iframe加载并切换 wait = WebDriverWait(driver, 10) comment_iframe = wait.until(EC.presence_of_element_located((By.XPATH, '//iframe[contains(@src, "spot.im")]'))) driver.switch_to.frame(comment_iframe) # 定位评论文本 comments = wait.until(EC.presence_of_all_elements_located((By.XPATH, '//div[@data-spot-im-class="message-text"]/p'))) for comment in comments: print(comment.text) # 操作完成后切回主文档(如需继续操作主页面) driver.switch_to.default_content()
2. 用显式等待替代直接查找
评论区是异步加载的,直接点击后立刻定位会因元素未渲染完成失败,必须用WebDriverWait确保元素加载完成。
3. 优先使用稳定定位属性
你之前用的长class名是自动生成的,易随网站更新变化,优先选择data-spot-im-class="message-text"这类语义化自定义属性。
4. 模拟真实浏览器规避反爬
Yahoo可能检测Selenium特征,可添加参数模拟真实浏览器:
options = webdriver.ChromeOptions() options.add_argument('--disable-blink-features=AutomationControlled') options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36') driver = webdriver.Chrome(options=options)
内容的提问来源于stack exchange,提问作者xlasdjfalsk782
相关产品推荐
相关产品推荐

