fj1*_*123 71 selenium screenshot selenium-webdriver
目前我正在尝试使用Selenium WebDriver捕获屏幕截图.但我只能获得整页屏幕截图.但是,我想要的只是捕获页面的一部分,或者只是基于ID或任何特定元素定位器捕获特定元素.(例如,我希望用图像id ="Butterfly"捕获图片)
有没有办法按选定的项目或元素捕获屏幕截图?
Sur*_*rya 102
我们可以通过裁剪整个页面截图来获取元素截图,如下所示:
driver.get("http://www.google.com");
WebElement ele = driver.findElement(By.id("hplogo"));
// Get entire page screenshot
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
BufferedImage fullImg = ImageIO.read(screenshot);
// Get the location of element on the page
Point point = ele.getLocation();
// Get width and height of the element
int eleWidth = ele.getSize().getWidth();
int eleHeight = ele.getSize().getHeight();
// Crop the entire page screenshot to get only element screenshot
BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), point.getY(),
eleWidth, eleHeight);
ImageIO.write(eleScreenshot, "png", screenshot);
// Copy the element screenshot to disk
File screenshotLocation = new File("C:\\images\\GoogleLogo_screenshot.png");
FileUtils.copyFile(screenshot, screenshotLocation);
Run Code Online (Sandbox Code Playgroud)
amb*_*odi 10
在Node.js,我编写了以下代码,但它不是基于selenium的官方WebDriverJS,而是基于SauceLabs's WebDriver:WD.js和一个非常紧凑的图像库,名为EasyImage.
我只想强调你不能真正拍摄元素的截图,但你应该做的是首先,截取整个页面的截图,然后选择你喜欢的页面部分并裁剪特定部分:
browser.get(URL_TO_VISIT)
.waitForElementById(dependentElementId, webdriver.asserters.isDisplayed, 3000)
.elementById(elementID)
.getSize().then(function(size) {
browser.elementById(elementID)
.getLocation().then(function(location) {
browser.takeScreenshot().then(function(data) {
var base64Data = data.replace(/^data:image\/png;base64,/, "");
fs.writeFile(filePath, base64Data, 'base64', function(err) {
if (err) {
console.log(err);
}
else {
cropInFile(size, location, filePath);
}
doneCallback();
});
});
});
});
Run Code Online (Sandbox Code Playgroud)
而cropInFileFunction就是这样的:
var cropInFile = function(size, location, srcFile) {
easyimg.crop({
src: srcFile,
dst: srcFile,
cropwidth: size.width,
cropheight: size.height,
x: location.x,
y: location.y,
gravity: 'North-West'
},
function(err, stdout, stderr) {
if (err) throw err;
});
};
Run Code Online (Sandbox Code Playgroud)
这是使用Selenium Webdriver和Pillow的Python 3版本。该程序捕获整个页面的屏幕快照,并根据其位置裁剪元素。元素图像将以image.png的形式提供。Firefox支持使用element.screenshot_as_png('image_name')直接保存元素图像。
from selenium import webdriver
from PIL import Image
driver = webdriver.Chrome()
driver.get('https://www.google.co.in')
element = driver.find_element_by_id("lst-ib")
location = element.location
size = element.size
driver.save_screenshot("shot.png")
x = location['x']
y = location['y']
w = size['width']
h = size['height']
width = x + w
height = y + h
im = Image.open('shot.png')
im = im.crop((int(x), int(y), int(width), int(height)))
im.save('image.png')
Run Code Online (Sandbox Code Playgroud)
更新资料
现在,chrome还支持单个元素的屏幕截图。因此,您可以直接捕获Web元素的屏幕截图,如下所示。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.google.co.in')
image = driver.find_element_by_id("lst-ib").screenshot_as_png
# or
# element = driver.find_element_by_id("lst-ib")
# element.screenshot_as_png("image.png")
Run Code Online (Sandbox Code Playgroud)
小智 8
Yandex的ASHOT框架可用于在Selenium WebDriver脚本中截取屏幕截图
该框架可以在https://github.com/yandex-qatools/ashot上找到.
截取屏幕截图的代码非常简单:
整页
screenshot = new AShot().shootingStrategy(
new ViewportPastingStrategy(1000)).takeScreenshot(driver);
ImageIO.write(screenshot.getImage(), "PNG", new File("c:\\temp\\results.png"));
Run Code Online (Sandbox Code Playgroud)
特定的Web元素
screenshot = new AShot().takeScreenshot(driver,
driver.findElement(By.xpath("(//div[@id='ct_search'])[1]")));
ImageIO.write(screenshot.getImage(), "PNG", new File("c:\\temp\\div_element.png"));
Run Code Online (Sandbox Code Playgroud)
查看更多的细节和更多的代码样本这篇文章.
对于每个要求使用 C# 代码的人,下面是我的实现的简化版本。
public static void TakeScreenshot(IWebDriver driver, IWebElement element)
{
try
{
string fileName = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".jpg";
Byte[] byteArray = ((ITakesScreenshot)driver).GetScreenshot().AsByteArray;
System.Drawing.Bitmap screenshot = new System.Drawing.Bitmap(new System.IO.MemoryStream(byteArray));
System.Drawing.Rectangle croppedImage = new System.Drawing.Rectangle(element.Location.X, element.Location.Y, element.Size.Width, element.Size.Height);
screenshot = screenshot.Clone(croppedImage, screenshot.PixelFormat);
screenshot.Save(String.Format(@"C:\SeleniumScreenshots\" + fileName, System.Drawing.Imaging.ImageFormat.Jpeg));
}
catch (Exception e)
{
logger.Error(e.StackTrace + ' ' + e.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
蟒蛇3
尝试使用 Selenium 3.141.0 和 chromedriver 73.0.3683.68,这有效,
from selenium import webdriver
chromedriver = '/usr/local/bin/chromedriver'
chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_argument('window-size=1366x768')
chromeOptions.add_argument('disable-extensions')
cdriver = webdriver.Chrome(options=chromeOptions, executable_path=chromedriver)
cdriver.get('url')
element = cdriver.find_element_by_css_selector('.some-css.selector')
element.screenshot_as_png('elemenent.png')
Run Code Online (Sandbox Code Playgroud)
无需获取完整图像并获取全屏图像的一部分。
创建罗希特的答案时,这可能不可用。
小智 5
我在截图上浪费了很多时间,我想保存你的截图。我用了铬+硒+ c#,结果太可怕了。最后我写了一个函数:
driver.Manage().Window.Maximize();
RemoteWebElement remElement = (RemoteWebElement)driver.FindElement(By.Id("submit-button"));
Point location = remElement.LocationOnScreenOnceScrolledIntoView;
int viewportWidth = Convert.ToInt32(((IJavaScriptExecutor)driver).ExecuteScript("return document.documentElement.clientWidth"));
int viewportHeight = Convert.ToInt32(((IJavaScriptExecutor)driver).ExecuteScript("return document.documentElement.clientHeight"));
driver.SwitchTo();
int elementLocation_X = location.X;
int elementLocation_Y = location.Y;
IWebElement img = driver.FindElement(By.Id("submit-button"));
int elementSize_Width = img.Size.Width;
int elementSize_Height = img.Size.Height;
Size s = new Size();
s.Width = driver.Manage().Window.Size.Width;
s.Height = driver.Manage().Window.Size.Height;
Bitmap bitmap = new Bitmap(s.Width, s.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, s);
bitmap.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);
RectangleF part = new RectangleF(elementLocation_X, elementLocation_Y + (s.Height - viewportHeight), elementSize_Width, elementSize_Height);
Bitmap bmpobj = (Bitmap)Image.FromFile(filePath);
Bitmap bn = bmpobj.Clone(part, bmpobj.PixelFormat);
bn.Save(finalPictureFilePath, System.Drawing.Imaging.ImageFormat.Png);
Run Code Online (Sandbox Code Playgroud)
如果您不介意涉及磁盘 IO,Surya 的答案非常有效。如果您不愿意,那么此方法可能更适合您
private Image getScreenshot(final WebDriver d, final WebElement e) throws IOException {
final BufferedImage img;
final Point topleft;
final Point bottomright;
final byte[] screengrab;
screengrab = ((TakesScreenshot) d).getScreenshotAs(OutputType.BYTES);
img = ImageIO.read(new ByteArrayInputStream(screengrab));
//crop the image to focus on e
//get dimensions (crop points)
topleft = e.getLocation();
bottomright = new Point(e.getSize().getWidth(),
e.getSize().getHeight());
return img.getSubimage(topleft.getX(),
topleft.getY(),
bottomright.getX(),
bottomright.getY());
}
Run Code Online (Sandbox Code Playgroud)
如果您愿意,可以跳过声明screengrab并执行
img = ImageIO.read(
new ByteArrayInputStream(
((TakesScreenshot) d).getScreenshotAs(OutputType.BYTES)));
Run Code Online (Sandbox Code Playgroud)
这更干净,但为了清楚起见我将其保留下来。然后您可以将其另存为文件或将其放入 JPanel 中,随心所欲。
我认为这里的大多数答案都是过度设计的。我这样做的方法是通过 2 个辅助方法,第一个方法等待基于任何选择器的元素;第二个是截取屏幕截图。
注意:我们将 投射WebElement到一个TakesScreenshot实例,因此我们只专门捕获图像中的该元素。如果您想要完整的页面/窗口,则应该进行强制driver转换。
编辑:我忘了说我正在使用 Java 和 Selenium v3(但 v4 应该相同)
WebDriver driver = new FirefoxDriver(); // define this somewhere (or chrome etc)
public <T> T screenshotOf(By by, long timeout, OutputType<T> type) {
return ((TakesScreenshot) waitForElement(by, timeout))
.getScreenshotAs(type);
}
public WebElement waitForElement(By by, long timeout) {
return new WebDriverWait(driver, timeout)
.until(driver -> driver.findElement(by));
}
Run Code Online (Sandbox Code Playgroud)
然后只需截图你想要的任何东西,如下所示:
long timeout = 5; // in seconds
/* Screenshot (to file) based on first occurence of tag */
File sc = screenshotOf(By.tagName("body"), timeout, OutputType.FILE);
/* Screenshot (in memory) based on CSS selector (e.g. first image in body
who's "src" attribute starts with "https") */
byte[] sc = screenshotOf(By.cssSelector("body > img[href^='https']"), timeout, OutputType.BYTES);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
83767 次 |
| 最近记录: |