Selenium批量截图5000网站:如何等待含框架页面完全加载并解决白屏?
解决Selenium页面截图空白/内容缺失的实用方案
针对批量截图5000个网站时遇到的页面未完全加载、截图空白问题,以下是几个直接有效的解决方法:
1. 替换readyState等待,改用网络空闲+动态渲染等待
document.readyState === "complete"仅表示基础资源加载完成,无法覆盖现代网站的异步动态内容(比如AJAX请求、框架渲染组件)。改用等待页面网络请求全部完成,再加短时间延迟确保渲染:
from selenium.webdriver.support.ui import WebDriverWait from selenium.common.exceptions import TimeoutException import time def wait_for_page_idle(driver, timeout=30): try: # 等待所有资源请求完成(无pending状态) WebDriverWait(driver, timeout).until( lambda d: d.execute_script(""" return window.performance.getEntriesByType('resource').every(entry => entry.responseEnd > 0 && entry.requestStart > 0 ); """) ) # 额外等待2秒,确保动态组件渲染完毕 driver.execute_script("return new Promise(resolve => setTimeout(resolve, 2000));") except TimeoutException: # 超时后强制继续,避免批量任务卡住 pass def visit_url(driver, url): driver.get(f"http://{url}") wait_for_page_idle(driver) driver.save_screenshot(f"data/screenshots/{url}.png")
2. 遍历等待所有iframe加载
很多网站用iframe加载广告、第三方内容,默认不会等待iframe内部加载,导致对应区域空白。添加iframe处理逻辑:
from selenium.webdriver.common.by import By def wait_for_all_iframes(driver, timeout=15): try: iframes = driver.find_elements(By.TAG_NAME, "iframe") for iframe in iframes: try: driver.switch_to.frame(iframe) # 等待iframe内部页面加载完成 WebDriverWait(driver, timeout).until( lambda d: d.execute_script("return document.readyState") == "complete" ) driver.switch_to.default_content() except Exception: # 跳过跨域或无法访问的iframe driver.switch_to.default_content() continue except Exception: pass
在wait_for_page_idle之后调用这个函数即可。
3. 调整窗口尺寸+触发懒加载内容
响应式网站在小窗口下可能不渲染全部内容,部分图片/内容采用懒加载(仅进入视口才加载):
# 初始化driver时设置窗口为标准尺寸 driver.set_window_size(1920, 1080) # 或者最大化窗口 driver.maximize_window() def trigger_lazy_load(driver): # 滚动到页面底部触发懒加载 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(1) # 再滚动回顶部,确保顶部内容正常显示 driver.execute_script("window.scrollTo(0, 0);")
将trigger_lazy_load(driver)加入截图前的流程。
4. 等待所有图片加载完成
部分截图空白是因为图片还没加载完毕,添加图片加载等待:
def wait_for_all_images(driver, timeout=20): try: WebDriverWait(driver, timeout).until( lambda d: d.execute_script(""" return Array.from(document.images).every(img => img.complete && img.naturalHeight > 0); """) ) except TimeoutException: pass
5. 全页面截图(针对长页面)
默认save_screenshot仅截取可见区域,长页面会出现内容截断,改用全页面截图:
def full_page_screenshot(driver, save_path): total_height = driver.execute_script("return document.body.scrollHeight") driver.set_window_size(1920, total_height) time.sleep(1) driver.save_screenshot(save_path)
6. 排查JS错误影响渲染
你的Cookie拦截扩展可能导致部分网站JS报错,阻塞页面渲染。可以打印浏览器日志排查:
logs = driver.get_log('browser') for log in logs: if log['level'] == 'SEVERE': print(f"[{url}] 严重JS错误: {log['message']}")
如果是扩展导致的,可临时禁用扩展测试,或调整扩展规则。
内容的提问来源于stack exchange,提问作者Jorn
相关产品推荐
相关产品推荐

