1. 들어가기 전에
이런 경우가 있다. 웹서버는 살아있지만 웹화면은 에러로 줄이 가 있거나 로딩이 완료 되지 않거나 시간이 오려 걸리거나 하는 사태가 벌어진다. 원인은 대부분 배경화면에 너무 나도 큰 빅사이즈의 이미지를 걸어 둔 경우 이다. 아니면 데이터를 받아서 그래프를 그리는 경우 화면이 다 완성되지 않고 200OK를 리턴하는 경우가 상당 수 있다. 아니면 어떤 특정 경우 즉 이웃 사이트에서 데이터를 받아서 그래프를 그리는데 그 사이트가 자주 장애가 난다면 이런 장애를 어떻게 감지 할 수 있을까?
웹을 자바로 캡쳐할 수 있는 소스 입니다.
2. 단점과 극복해야 하는 점
일단 자바 웹 캡쳐는 JRE 1.8로 더 이상 업데이트가 없다. 지금 라이브러리는 1.8을 사용하고 있다. cromdriver는 아직 되지만 실제 하위 드라이브가 안 될 수도 있다. 그래서 추후 개발을 한다면 python가 자바의 콜라보가 필요할 수 있다. 먼저 eclipse의 java 프로젝트를 하나 만든다.
src 폴더에 패키지는 아무거나 추가 한다. kr.co.xxx로 해도 되고 그냥 webcap 이라고 해도 된다.
jbrowserTest.java
package screenshot;
import com.machinepublishers.jbrowserdriver.JBrowserDriver;
import com.machinepublishers.jbrowserdriver.Settings;
import com.machinepublishers.jbrowserdriver.Timezone;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.OutputType;
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
import ru.yandex.qatools.ashot.shooting.ShootingStrategies;
import javax.imageio.ImageIO;
import java.io.*;
public class JbrowserTest {
public String chekUrl(String str){
if (str.startsWith("http://") || str.startsWith("https://")) {
return str;
}
return str;
}
public static void main(String[] args) throws UnsupportedEncodingException {
// You can optionally pass a Settings object here,
// constructed using Settings.Builder
JBrowserDriver driver = new JBrowserDriver(Settings.builder().connectTimeout(20000).connectionReqTimeout(20000).ajaxResourceTimeout(20000).
timezone(Timezone.ASIA_SEOUL).screen(new Dimension(1920,1080)).build());
//String url3 = "http://www.google.com";
String url3 = "http://www.nkd.or.kr";
// This will block for the page load and any
// associated AJAX requests
long beforeTime = System.currentTimeMillis(); //코드 실행 전에 시간 받아오기
System.out.println("start time : " + beforeTime);
driver.get(url3);
driver.manage().window().maximize();
// You can get status code unlike other Selenium drivers.
// It blocks for AJAX requests and page loads after clicks
// and keyboard events.
System.out.println(driver.getStatusCode());
long afterTime = System.currentTimeMillis(); // 코드 실행 후에 시간 받아오기
System.out.println("end time : " + afterTime);
long secDiffTime = (afterTime - beforeTime)/1000; //두 시간에 차 계산
System.out.println("시간차이 1차(Sec) : "+secDiffTime);
// Returns the page source in its current state, including
// any DOM updates that occurred after page load
//String string2 = new String(driver.getPageSource().getBytes("utf-8"),"gb2312");
//String string2 = new String(driver.getPageSource().getBytes("utf-8"),"euc-kr");
String string2 = new String(driver.getPageSource().getBytes("utf-8"));
System.out.println(string2);
//ShootingStrategy ss = ShootingStrategies.viewportPasting(100);
//org.openqa.selenium.internal.Killable ka = new JbrowserTest();
afterTime = System.currentTimeMillis(); // 코드 실행 후에 시간 받아오기
System.out.println("end time : " + afterTime);
secDiffTime = (afterTime - beforeTime)/1000; //두 시간에 차 계산
System.out.println("시간차이 2차(Sec) : "+secDiffTime);
AShot as = new AShot();
Screenshot screenshot2 = as
// .takeScreenshot(driver);
//as.takeScreenshot(driver);
.shootingStrategy(ShootingStrategies.viewportPasting(100))
.takeScreenshot(driver);
try {
ImageIO.write(screenshot2.getImage(), "PNG",
new File("c:/mywork/test1.png"));
// byte[] screenshot = driver.getScreenshotAs(OutputType.BYTES);
// System.out.println("the bytes" + screenshot.length);
// String filePath = "c:/work/test.png";
// File file = new File(filePath);
// FileOutputStream fw = new FileOutputStream(file);
// fw.write(screenshot);
// fw.close();
} catch (Exception ex) {
System.out.println("error" + ex);
}
// Close the browser. Allows this thread to terminate.
driver.quit();
}
}
WebScreenShot.java
package screenshot;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class WebScreenShot {
private void loadWebpage() throws IOException{
//Init driver
System.setProperty("webdriver.chrome.driver","C:/work/chromedriver/chromedriver.exe");
ChromeOptions options = new ChromeOptions();
//options.setHeadless(true);
options.addArguments("--window-size=1200x600", "--log-level=3");
WebDriver driver = new ChromeDriver(options);
//Load your website & wait until loaded with webdriver wait
WebScreenShot.takeScreenShot(driver, new File("outputFile.png"));
}
private static void takeScreenShot(WebDriver driver, File screenshotFile) throws IOException {
// TODO Auto-generated method stub
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Files.copy(scrFile.toPath(), screenshotFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
public static void takeScreenshot(WebDriver driver, File screenshotFile) throws IOException {
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Files.copy(scrFile.toPath(), screenshotFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
public static void main(String[] args) throws IOException {
WebScreenShot wss = new WebScreenShot();
wss.loadWebpage();
}
}
위의 소스가 실행 되려면 위의 lib가 필요 합니다. 먼저 프로젝트 안에 lib를 풀고 build path config에서 해당 폴더를 lib 폴더로 추가 해야 합니다. 추세적으로 웹캡쳐가 어떤 이유로 없어지고 있는 상황이라 자바는 1.8이 거의 마지막 버젼일 것 같습니다.
아직 crom driver나 Firefox 등에서 드라이브가 나오고 있지만 python 호환인 경우가 많습니다.
가만하시고 보시면 될 것 같습니다. 원래 maven 프로젝트였으나 라이브러리가 없어지기 전에 제가 한땀 한땀 받아서 모아 났습니다. 참고해서 잘 사용하시기 바랍니다.