Selenium定位可见元素失败求助:mail.com邮件抓取异常
问题:Selenium定位mail.com邮件列表元素时抛出NoSuchElementException
尝试用Selenium抓取mail.com的前两封邮件,登录及跳转至邮件页面的流程均正常,但在定位邮件列表元素时,明明元素已可见,却抛出NoSuchElementException异常。已尝试使用XPATH和CSS_SELECTOR两种定位方式,且在开发者工具中能搜索到该元素,请求解决方法。
异常信息
raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"#maillist"} (Session info: chrome=115.0.5790.110); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception Stacktrace: Backtrace: GetHandleVerifier [0x00007FF60B2D4A62+57106] (No symbol) [0x00007FF60B24CF52] (No symbol) [0x00007FF60B11E2CB] (No symbol) [0x00007FF60B15786E] (No symbol) [0x00007FF60B15795C] (No symbol) [0x00007FF60B190477] (No symbol) [0x00007FF60B1769FF] (No symbol) [0x00007FF60B18E522] (No symbol) [0x00007FF60B176793] (No symbol) [0x00007FF60B14CE81] (No symbol) [0x00007FF60B14E064] GetHandleVerifier [0x00007FF60B584222+2873042] GetHandleVerifier [0x00007FF60B5D6590+3209792] GetHandleVerifier [0x00007FF60B5CF3AF+3180639] GetHandleVerifier [0x00007FF60B365F25+652245] (No symbol) [0x00007FF60B258618] (No symbol) [0x00007FF60B2547C4] (No symbol) [0x00007FF60B2548BC] (No symbol) [0x00007FF60B244C33] BaseThreadInitThunk [0x00007FFAE7C87614+20] RtlUserThreadStart [0x00007FFAE99A26F1+33]
使用的代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from time import sleep if __name__ == "__main__": #Variables email = input("Email: ") password = input("Password: ") #Xpaths login_form_xpath = "/html/body/div[1]/div/div[1]/header/div[1]/div[3]/a[2]" email_input_xpath = "/html/body/div[1]/div/div[1]/div/div/div/div[2]/form/div[1]/input" password_input_xpath = "/html/body/div[1]/div/div[1]/div/div/div/div[2]/form/div[2]/input" login_button_xpath = "/html/body/div[1]/div/div[1]/div/div/div/div[2]/form/button" email_screen_xpath = "/html/body/nav/nav-actions-menu/div[1]/div[1]/a[2]" inbox_table_div_xpath = "/html/body/div[3]/div[3]/div[3]/div[1]/div[1]/div/form/div[3]" #Initiate driver options = webdriver.ChromeOptions() options.add_argument("--enable-javascript") driver = webdriver.Chrome(options=options) driver.get("https://www.mail.com/") #Go to login WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, login_form_xpath))) driver.find_element(By.XPATH, login_form_xpath).click() #Input Email / Password WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, email_input_xpath))) driver.find_element(By.XPATH, email_input_xpath).send_keys(email) driver.find_element(By.XPATH, password_input_xpath).send_keys(password) driver.find_element(By.XPATH, login_button_xpath).click() #Go to emails WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, email_screen_xpath))) driver.find_element(By.XPATH, email_screen_xpath).click() #Get emails sleep(15) # table = driver.find_element(By.XPATH, inbox_table_div_xpath) table = driver.find_element(By.CSS_SELECTOR, "#maillist") with open('abc.html', 'w', encoding='utf-8') as f: f.write(table.get_attribute("innerHtml")) sleep(300)
解决方法
检查iframe存在性:邮件列表很可能嵌套在iframe中,Selenium默认只会在主文档查找元素,需要先切换到对应iframe:
# 等待iframe加载完成并切换 iframe = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "对应的iframeID"))) driver.switch_to.frame(iframe) # 之后再定位邮件列表元素 table = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "#maillist"))) # 操作完成后若需回到主文档,执行: # driver.switch_to.default_content()可以在开发者工具中搜索
iframe标签,找到包裹邮件列表的那个iframe的定位符(ID、class等)。替换绝对XPATH为相对定位:你当前使用的绝对XPATH(如
/html/body/...)依赖页面DOM结构,一旦页面布局微调就会失效,改用相对定位更稳定:
比如邮件列表的相对XPATH可以写为//div[@id='maillist'],直接用CSS选择器#maillist也更简洁。用显式等待替代固定sleep:
sleep(15)是固定等待时间,无法适配不同加载速度,改用WebDriverWait等待元素状态:# 等待元素可见并可定位 table = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.CSS_SELECTOR, "#maillist")) )根据需求选择合适的等待条件:
presence_of_element_located(元素存在于DOM)、visibility_of_element_located(元素可见)、element_to_be_clickable(元素可点击)。排查动态加载逻辑:邮件列表可能通过AJAX异步加载,显式等待能自动等待元素加载完成,比固定sleep更可靠。
内容的提问来源于stack exchange,提问作者Syed Abdullah
相关产品推荐
相关产品推荐

