requests+BeautifulSoup无法抓取动态生成的图片,因其仅获取原始HTML,而JavaScript渲染的内容(如fetch加载、Canvas绘图、懒加载)在源码中不存在;需用Selenium等待元素加载后再截图或提取base64数据。

为什么 requests + BeautifulSoup 抓不到动态图片
页面里用 JavaScript 生成的 <img alt="Python爬虫如何抓取动态生成图片_结合Selenium截图并保存到本地" > 标签(比如通过 fetch 加载、Canvas 渲染、或懒加载后插入 DOM),requests 拿到的原始 HTML 里根本不存在这些标签,BeautifulSoup 自然解析不出来。这时候不是“解析错了”,而是“压根没加载出来”。
- 典型表现:检查网页源代码(Ctrl+U)找不到目标图片的
src,但浏览器开发者工具(F12)的 Elements 面板里能看到 - 常见场景:验证码图、商品详情页缩略图、图表类图片(ECharts / Chart.js 渲染)、带水印的 canvas 输出图
- 直接请求
src地址失败?可能是临时 token、Referer 校验、或图片由前端 JS 动态拼接 URL(如src="data:image/png;base64,..."或canvas.toDataURL())
用 Selenium 截图前必须等什么
截图早了,页面还没渲染完,截出来是空白或缺元素;截图晚了,又浪费时间。关键不是“等几秒”,而是等具体条件满足。
- 优先用
WebDriverWait等待图片容器元素存在且可见:presence_of_element_located+visibility_of_element_located - 如果图片是
canvas或 SVG,要等其父容器尺寸稳定,否则截图可能裁切异常 —— 可加time.sleep(0.5)微调,但别依赖它 - 遇到
StaleElementReferenceException?说明 DOM 刷新了,得重新定位元素,不能复用旧的WebElement - 避免用
driver.execute_script("return document.readyState") == "complete",有些 SPA 页面始终不触发complete
截图保存时要注意哪些路径和格式细节
screenshot() 和 screenshot_as_png 行为不同,保存方式也影响可维护性。
-
element.screenshot("path/to/file.png"):只截元素可视区域,但会自动处理overflow: hidden和滚动位置 —— 适合截单张图,但不支持指定质量或格式 -
driver.get_screenshot_as_png():截整个视口,返回bytes,需手动用PIL.Image打开再裁剪/压缩,适合批量处理或加水印 - 保存路径含中文或空格?务必用
os.path.join()拼接,并确保目录已存在:os.makedirs(os.path.dirname(save_path), exist_ok=True) - 截图文件名别硬编码,建议用 URL 的 hash 或时间戳 + 序号,避免覆盖:
f"img_{hashlib.md5(url.encode()).hexdigest()[:8]}.png"
如何处理 canvas 渲染图和 base64 图片
很多动态图实际是 canvas 绘制后转成 data: URL,或者直接用 JS 注入 src。这两种情况都不能靠 get_attribute("src") 直接下载。
立即学习“Python免费学习笔记(深入)”;
- 对
canvas元素,执行 JS 获取 base64:driver.execute_script("return arguments[0].toDataURL('image/png');", canvas_elem),再用base64.b64decode()写入文件 - 对
data:image/xxx;base64,...类型的src,先用正则提取 base64 字符串(注意去掉前缀),再解码保存 - base64 解码后写文件时,必须用
open(..., "wb"),不能用"w",否则报错UnicodeEncodeError - 某些站点会禁用
toDataURL()(如设置了crossOrigin但未配 CORS),此时只能退回到全屏截图 + OCR,或换 Headless Chrome 启动参数:--disable-web-security(仅测试环境)
真正麻烦的不是截图本身,而是判断该截哪一块、等哪个信号、以及 base64 解码后要不要做 PNG 压缩或尺寸归一化 —— 这些都得按目标网站的具体行为来定,没有通用模板。


















