Selenium爬取币安公告遇ElementNotInteractable等异常求助
解决币安新币公告爬取的Selenium异常问题
处理ElementNotInteractableException
- 放弃用
presence_of_element_located定位链接,币安的公告链接是动态渲染的,必须确保元素可见且可交互,改用visibility_of_element_located或visibility_of_all_elements_located。 - 调试模式无报错是因为手动操作时页面完全加载,自动化时直接点击容易触发交互限制,用
execute_script模拟点击可以绕过这个问题:driver.execute_script("arguments[0].click();", target_element) - 先处理Cookie弹窗这类干扰元素,避免它们遮挡公告链接。
解决StaleElementReferenceException
这个异常的本质是:你回到列表页后,之前获取的链接元素引用已经失效(DOM被刷新了)。解决核心是不要复用旧的元素列表:
- 每次从公告详情页返回列表页后,重新定位所有公告链接,不要用之前缓存的列表。
- 用索引记录已处理的公告,避免重复爬取,分页后重置索引。
完整可运行代码示例
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time # 初始化浏览器 driver = webdriver.Chrome() wait = WebDriverWait(driver, 15) base_url = "https://www.binance.com/en/support/announcement/new-cryptocurrency-listing?c=48&navId=48" driver.get(base_url) # 处理Cookie弹窗(如果出现) try: cookie_accept_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".css-1mhnkuh"))) cookie_accept_btn.click() time.sleep(1) except: pass # 无弹窗则跳过 processed_ids = [] # 记录已处理的公告索引 while True: # 每次回到列表页后,重新获取所有公告链接 all_links = wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, ".css-1ej4hfo a"))) # 遍历未处理的链接 for idx, link in enumerate(all_links): if idx in processed_ids: continue # JS点击避免交互异常 driver.execute_script("arguments[0].click();", link) # 等待详情页内容加载 try: announcement_content = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".css-1wddh8y"))).text print(f"公告{idx+1}内容:\n{announcement_content}\n") except Exception as e: print(f"公告{idx+1}加载失败: {str(e)}") # 返回列表页并等待DOM刷新 driver.back() wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".css-1ej4hfo"))) processed_ids.append(idx) # 处理分页 try: next_page = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".css-1qyp7xa:last-child"))) # 判断是否为最后一页 if "disabled" in next_page.get_attribute("class"): break driver.execute_script("arguments[0].click();", next_page) # 等待分页后的DOM更新 wait.until(EC.staleness_of(all_links[0])) processed_ids = [] # 分页后重置已处理索引 time.sleep(1) except: break # 无下一页则退出 driver.quit()
额外提示
- 币安的页面CSS选择器可能会更新,如果代码报错,先检查选择器是否失效。
- 不要把等待时间设得太短,显式等待比
time.sleep更可靠,但必要时可以加短时间sleep辅助。 - 频繁请求可能触发反爬,建议控制爬取速度,不要过于激进。
内容的提问来源于stack exchange,提问作者Angela
相关产品推荐
相关产品推荐

