使用Selenium爬取网页数据不一致,无法获取完整数据
爬取页面数据异常:内容错误且列表不完整
问题重现
爬取目标页面https://lambda-app-eia.herokuapp.com/时,使用以下代码:
from selenium import webdriver from selenium.webdriver.common.by import By import time from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--headless') chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-dev-shm-usage') driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options) driver.get("https://lambda-app-eia.herokuapp.com/")
通过CSS选择器抓取元素并提取文本:
elements = driver.find_elements(By.CSS_SELECTOR, ".MuiTypography-root.MuiTypography-h4.css-2voflx") job_list = [ job.text for job in elements]
得到的结果不符合预期:
['2PSI', '41CELCIUS', '56%', '200PPM']
实际第一个数据应为2ATM,且列表可能存在遗漏。
原因分析
- 动态内容未完全加载:页面中的第一个数据存在文本切换动画(从
2PSI变为2ATM),Selenium在元素文本未完成更新时就执行了抓取操作。 - Headless模式渲染限制:默认Headless模式下浏览器窗口尺寸较小,可能导致页面元素渲染不完整或动画执行异常。
- 缺少显式等待:仅依赖页面加载完成事件,未等待目标元素的文本内容稳定。
解决方案
1. 添加显式等待,确保文本内容稳定
使用WebDriverWait等待目标元素的文本更新为预期值,同时确保所有元素加载完成:
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 chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--headless') chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-dev-shm-usage') # 添加窗口大小参数,避免Headless模式渲染异常 chrome_options.add_argument('--window-size=1920,1080') # 新版Selenium推荐使用options参数而非chrome_options driver = webdriver.Chrome('chromedriver', options=chrome_options) driver.get("https://lambda-app-eia.herokuapp.com/") wait = WebDriverWait(driver, 10) # 等待所有目标元素存在 wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".MuiTypography-root.MuiTypography-h4.css-2voflx"))) # 等待第一个元素的文本更新为2ATM,确保动画完成 wait.until(lambda driver: driver.find_element(By.CSS_SELECTOR, ".MuiTypography-root.MuiTypography-h4.css-2voflx").text == "2ATM") # 重新抓取元素文本 elements = driver.find_elements(By.CSS_SELECTOR, ".MuiTypography-root.MuiTypography-h4.css-2voflx") job_list = [job.text for job in elements] print(job_list)
2. 优化选择器(可选)
如果动态类名(如css-2voflx)存在变更风险,可结合元素的其他属性构建更稳定的选择器,例如:
.MuiTypography-h4[aria-label*="pressure"]
根据页面元素的实际属性调整,避免依赖动态生成的class。
3. 增加页面等待时间(简易方案)
若不想使用显式等待,可在页面加载后增加固定等待时间,确保动画完成:
driver.get("https://lambda-app-eia.herokuapp.com/") time.sleep(3) # 等待3秒让动画执行完成 elements = driver.find_elements(By.CSS_SELECTOR, ".MuiTypography-root.MuiTypography-h4.css-2voflx") job_list = [job.text for job in elements]
内容的提问来源于stack exchange,提问作者Qxap
相关产品推荐
相关产品推荐

