PhantomJS截图网站div为Spring MVC,Tomcat和iText使用

时间:2014-02-22 04:31:03

标签: java spring selenium itext phantomjs

我已经了解了PhantomJS和CasperJS的强大功能,以获取网站截图。文章“Responsive Screenshots With Casper”非常有助于了解这两种技术的基础知识以及屏幕截图功能。

接下来是如何使用此技术与Spring MVC应用程序集成。

到目前为止,我已尝试使用“Screen Capture using PhantomJS, GhostDriver, Selenium Hub”代码并将其与“answer”中提供的Remote PhantomJS driver in Junit相结合。

发生的事情是,每次运行程序时,我都会持续ClassNotFoundError并且我一直提供缺少的JAR文件。我最终在Spring应用程序中下载并提供了九个新的JAR文件:

  • phantomjsdriver-1.0.4.jar
  • selenium-java-2.39.0.jar及其源文件
  • asm-all-3.3.1.jar
  • cglib-3.1.jar
  • commons-exec-1.2.jar
  • guava-16.0.1.jar
  • httpclient-4.3.2.jar
  • httpcore-4.3.2.jar
  • json-20140107.jar

直到下面的错误显示

SEVERE: Servlet.service() for servlet [spring] in context with path [/my_spring_app] threw exception [Handler processing failed; nested exception is java.lang.IncompatibleClassChangeError: class net.sf.cglib.core.DebuggingClassWriter has interface org.objectweb.asm.ClassVisitor as super class] with root cause
java.lang.IncompatibleClassChangeError: class net.sf.cglib.core.DebuggingClassWriter has interface org.objectweb.asm.ClassVisitor as super class

我是否应该继续尝试这条路径来获取我网站的截图?我觉得这是一场基于正在发生的事情的失败战斗。我对PhantomJS不熟悉,也无法在线找到任何合法的教程或指南。如果我不能做到这一点,我会回到iTextJFreeCharts

以下是我在Spring应用程序中使用的代码:

package my_spring_app.controller;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MyController {

    protected final static Log logger = LogFactory
            .getLog(MyController.class);

    @RequestMapping(value = "/screenshot", method = RequestMethod.GET)
    public String showSupplementsPage(ModelMap model,
            HttpServletRequest request, HttpServletResponse response) {

        tryPhantom();

        return "screenshot";
    }

    private URI uri;
    private static PhantomJSDriverService service;
    private WebDriver webDriver;
    protected static DesiredCapabilities dCaps;

    public void tryPhantom() {

        service = new PhantomJSDriverService.Builder()
                .usingPhantomJSExecutable(new File("classpath:phantomjs.exe"))
                .usingAnyFreePort().build();
        try {
            service.start();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            uri = new URI("http://localhost:8080/");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        dCaps = new DesiredCapabilities();
        dCaps.setJavascriptEnabled(true);
        dCaps.setCapability("takesScreenshot", true);

        webDriver = new RemoteWebDriver(service.getUrl(), dCaps);
        webDriver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

        long iStart = System.currentTimeMillis();
        webDriver.get("http://localhost:8080/");

        webDriver = new Augmenter().augment(webDriver);
        File srcFile = ((TakesScreenshot) webDriver)
                .getScreenshotAs(OutputType.FILE);
        System.out.println("File:" + srcFile);
        try {
            FileUtils.copyFile(srcFile, new File("classpath:screenshots/pic.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Single Page Time:"
                + (System.currentTimeMillis() - iStart));

        webDriver.quit();
        service.stop();
    }

}

以下是我的想法:

enter image description here

1 个答案:

答案 0 :(得分:2)

我是否应该继续尝试这条路径来获取我网站的截图? 我觉得这是一场基于正在发生的事情的失败战斗。

你是对的,我认为需要重新考虑管理依赖关系的方法,否则将无法使网站运行。手动逐个装载罐子不太可能产生良好的效果,因为不能保证库版本彼此兼容。

事实上IncompatibleClassChangeError表示下载的广告兼容。

你最好的选择是使用Maven自动下载大部分罐子。通过仅声明顶级jar,Maven将自动下载所需的依赖jar(传递依赖),有助于减少并在许多情况下消除库不兼容问题。

让网站启动并运行后,需要在Casper.js中编写一些脚本来访问本地服务器中的页面,单击某些按钮以生成PDF等,然后拍摄一些快照。

Spring MVC不需要特殊的集成,对于Spring MVC应用程序,如果PhantomJS或普通浏览器访问该站点,它是透明的。