使用selenium从页面保存图像

我正在使用Selenium和Google Chrome驱动程序以编程方式打开页面。 在每个页面上都有一个动态生成的图像,我想下载它。 目前,我正在等待页面完成加载,然后我抓取图像URL并使用System.Net.WebClient下载它。

这工作正常,除了我下载图像两次 – 一次在浏览器中,一次使用WebClient。 问题是每个图像大约是15MB,下载两次快速加起来。

那么 – 是否可以直接从谷歌浏览器中获取图像?

一种方法是使用webdriver执行的javascript获取图像的base64字符串。 然后,您可以将图像的base64string保存到文件。

基本上,如果你的形象是

 

然后你就可以转换它了

 var base64string = driver.ExecuteScript(@" var c = document.createElement('canvas'); var ctx = c.getContext('2d'); var img = document.getElementById('Img1'); c.height=img.height; c.width=img.width; ctx.drawImage(img, 0, 0,img.width, img.height); var base64String = c.toDataURL(); return base64String; ") as string; var base64 = base64string.Split(',').Last(); using (var stream = new MemoryStream(Convert.FromBase64String(base64))) { using (var bitmap = new Bitmap(stream)) { var filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ImageName.png"); bitmap.Save(filepath, ImageFormat.Png); } } 

是的,您可以通过几个步骤执行此操作:

  1. 获取网页的屏幕截图并将其保存到磁盘
  2. 找到图像元素
  3. 找到图像元素的位置,宽度和高度
  4. 从您在步骤1中截取的屏幕截图中裁剪所需的图像
  5. 将图像保存到磁盘(或使用它执行其他操作)

示例代码 – 请添加您的代码以捕获exception

  IWebDriver driver = new ChromeDriver(); //replace with the page you want to navigate to string your_page = "https://www.google.com"; driver.Navigate().GoToUrl(your_page); ITakesScreenshot ssdriver = driver as ITakesScreenshot; Screenshot screenshot = ssdriver.GetScreenshot(); Screenshot tempImage = screenshot; tempImage.SaveAsFile(@"C:\full.png", ImageFormat.Png); //replace with the XPath of the image element IWebElement my_image = driver.FindElement(By.XPath("//*[@id=\"hplogo\"]/canvas[1]")); Point point = my_image.Location; int width = my_image.Size.Width; int height = my_image.Size.Height; Rectangle section = new Rectangle(point, new Size(width, height)); Bitmap source = new Bitmap(@"C:\full.png"); Bitmap final_image = CropImage(source, section); final_image.Save(@"C:\image.jpg"); 

CropImage方法由James Hill发布, 如何在C#中剪切部分图像

但为了清楚起见,我也会在这里添加它

  public Bitmap CropImage(Bitmap source, Rectangle section) { Bitmap bmp = new Bitmap(section.Width, section.Height); Graphics g = Graphics.FromImage(bmp); g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel); return bmp; } 

您可以使用此技术阻止图像在Google Chrome中下载。 它运行名为“Block Image”的Google Chrome扩展程序。 这样就不会使用chrome下载图像,只需使用其URL和System.Net.WebClient正常下载图像即可。

以上所有答案都有效。 但是,它们都有局限性。 mecek的方法很酷,但它只适用于支持html 5的浏览器(尽管现在大多数浏览器都这样做),它会降低图像质量。 屏幕截图方法也会降低图像质量。 使用System.Net.WebClient可以避免此问题,但在下载validation码图像时不起作用。 实际上,下载validation码图像时唯一适用于我的方法是使用Actions类(如果使用Selenium的java版本,则使用Robot),如下所示:

 using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Interactions; using System.Windows.Automation;//you need to add UIAutomationTypes and UIAutomationClient to references using System.Runtime.InteropServices; [DllImport("User32.dll")] static extern int SetForegroundWindow(IntPtr point); private IntPtr getIntPtrHandle(IWebDriver driver, int timeoutSeconds = 30) { var end = DateTime.Now.AddSeconds(timeoutSeconds); while (DateTime.Now < end) { var ele = AutomationElement.RootElement; foreach (AutomationElement child in ele.FindAll(TreeScope.Children, Condition.TrueCondition)) { if (!child.Current.Name.Contains(driver.Title)) continue; return new IntPtr(child.Current.NativeWindowHandle); } } return IntPtr.Zero; } private void downloadCaptcha(IWebDriver chromeDriver) { OpenQA.Selenium.IWebElement captchaImage = chromeDriver.FindElement(By.Id("secimg0")); var handle = getIntPtrHandle(chromeDriver); SetForegroundWindow(handle);//you need ap/invoke Thread.Sleep(1500);//setting foreground window takes time Actions action = new Actions(chromeDriver); action.ContextClick(captchaImage).Build().Perform(); Thread.Sleep(300); SendKeys.Send("V"); var start = Environment.TickCount; while (Environment.TickCount - start < 2000) {//can't use Thread.Sleep here, alternatively you can use a Timer Application.DoEvents(); } SendKeys.SendWait(@"C:\temp\vImage.jpg"); SendKeys.SendWait("{ENTER}"); } 

这是我发现使用Selenium Chrome驱动程序下载validation码图像而不会失去其质量(以获得更好的OCR效果)的唯一方法,尽管限制也很明显。

 I'm using Selenium & Google Chrome Driver 

会谈selenium。

 once in the browser, once with WebClient 

Htmlunit?

无论如何,你为什么不使用webclient(htmlunit-driver)或纯htmlunit( http://htmlunit.sourceforge.net/ )。 Htmlunit默认不下载图像。

您可以根据您的要求随意下载它们。

您是否尝试使用ImageIO下载图像?

 String imageUrl = "image.png"; BufferedImage bufferedImage = ImageIO.read(imageUrl); ImageIO.write(bufferedImage, "png", new File("savedImage.png"));