如何使用Selenium Webdriver和C#实现网页图片保存
可行解决方案
下面给出2种经过验证的稳定实现方式,适配大部分场景:
注意:使用代码前需要先安装对应NuGet包:
Selenium.WebDriver、Selenium.WebDriver.ChromeDriver、Selenium.Support、SeleniumExtras.WaitHelpers
方案1:获取图片src后通过HttpClient下载(性能最高,适合绝大多数公开可访问的图片资源)
这个方案避开了第三方扩展的兼容性问题,直接拿到图片地址后发起标准HTTP请求下载,同时可以自定义请求头模拟浏览器请求,绕过基础反爬限制。
实现代码:
using System.IO; using System.Net.Http; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; using SeleniumExtras.WaitHelpers; // 初始化HttpClient建议*全局复用*,不要每次请求都新建 private static readonly HttpClient _httpClient = new HttpClient(); public void DownloadImage() { var driverService = ChromeDriverService.CreateDefaultService(); var opts = new ChromeOptions(); // 可选:添加请求头伪装正常浏览器访问 opts.AddArgument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); using var driver = new ChromeDriver(driverService, opts); driver.Navigate().GoToUrl("https://rd1.com.br/fora-da-globo-fausto-silva-recusa-convite-do-canal-para-homenagem/"); try { // 先加显式等待,确保图片元素加载完成再操作,避免找不到元素报错 var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); var imgElement = wait.Until(ExpectedConditions.ElementExists(By.XPath("//*[@id='post-1163172']/div[8]/ul/li[2]/div[1]/a/img"))); // 获取图片真实地址 string imgUrl = imgElement.GetAttribute("src"); // 携带浏览器Cookie发起请求,避免防盗链拦截 var cookieContainer = new System.Net.CookieContainer(); foreach (var cookie in driver.Manage().Cookies.AllCookies) { cookieContainer.Add(new Uri("https://rd1.com.br"), new System.Net.Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain)); } using var handler = new HttpClientHandler { CookieContainer = cookieContainer }; using var client = new HttpClient(handler); // 加Referer头绕过防盗链 client.DefaultRequestHeaders.Referrer = new Uri("https://rd1.com.br"); client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); // 下载保存 var imgBytes = client.GetByteArrayAsync(imgUrl).Result; File.WriteAllBytes(@"C:\temp\a.png", imgBytes); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { driver.Quit(); } }
方案2:直接截取目标图片元素(适配所有渲染后的图片,包括懒加载、加密链接、base64格式图片)
如果网站图片链接做了加密、防盗链严格无法直接下载,可以用Selenium 4+自带的元素截图功能,直接截取渲染后的图片元素,不需要获取图片地址。
实现代码:
using System.IO; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; using SeleniumExtras.WaitHelpers; public void ScreenshotImage() { var driverService = ChromeDriverService.CreateDefaultService(); var opts = new ChromeOptions(); using var driver = new ChromeDriver(driverService, opts); driver.Navigate().GoToUrl("https://rd1.com.br/fora-da-globo-fausto-silva-recusa-convite-do-canal-para-homenagem/"); try { var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); var imgElement = wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[@id='post-1163172']/div[8]/ul/li[2]/div[1]/a/img"))); // 直接对元素截图保存 var screenshot = imgElement.GetScreenshot(); screenshot.SaveAsFile(@"C:\temp\b.png", ScreenshotImageFormat.Png); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { driver.Quit(); } }
原有代码失效的常见原因
- 没有加加载等待,页面还没渲染完就查找元素,导致元素不存在报错
- 第三方扩展
gravity.code发起下载请求时没有携带当前页面的Cookie、Referer等头信息,被网站防盗链规则拦截 - 部分网站做了动态资源地址渲染,扩展读取的src属性不是最终可访问地址
内容的提问来源于stack exchange,提问作者Mil
相关产品推荐
相关产品推荐

