1.chrome headless简介

chrome headless是chrome浏览器的无界面模式,可以在不启用gui的情况下使用chrome浏览器的所有特性运行你的程序。这样更方便在Linux服务器上部署,同时可以方便用代码来操作浏览器,并且稳定性也有保证。使用chrome headless能够抓取很多需要登录的网站数据,甚至可以使用chrome获取cookie之后共享给其他的爬虫工具比如HttpClient ,OkHttp等。

2.开发环境
1.unbuntu18.04
2.jdk8
3.springboot
4.maven
5.selenium
3.环境搭建
  • chrome安装
    sudo apt-get install libxss1 libappindicator1 libindicator7
    wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
    sudo dpkg -i google-chrome*.deb  # Might show "errors", fixed by next line
    sudo apt-get install -f
    
  • webdriver安装

    在Ubuntu上下载最新的webdriver二进制包

    wget https://chromedriver.storage.googleapis.com/2.45/chromedriver_linux64.zip
    

    解压zip包

    unzip chromedriver_linux64.zip
    

    启动webdriver

    ./chromedriver -p 9515
    

    效果如下

image-20190130213406787.png
  • ssh端口转发

    做ssh端口转发的原因是webdriver限制了只能本机应用才能调用,但是开发的时候是在自己的开发机上,需要远程连接webdriver,所以需要将webdriver的端口转发出来也就是需要把9515这个端口映射到自己的开发机上。命令如下:

    ssh -L 9515:localhost:9515 bird@bird
    

    在做端口映射之前需要让开发机能够免密登录,部署chrome 以及webdriver的服务器。

    对ssh端口转发不懂得同学可以参考这篇文章

    https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/

    ssh免密登录很简单就不说了。

4.Java工程构建
  • 标准的maven工程 主要依赖

    org.springframework.boot
    spring-boot-starter-parent
    1.5.12.RELEASE
    
 


    org.springframework.boot
    spring-boot-starter-web



    org.springframework.boot
    spring-boot-starter-test
    test



    com.alibaba
    druid-spring-boot-starter
    1.1.10
 

    mysql
    mysql-connector-java
    5.1.44


    org.mybatis.spring.boot
    mybatis-spring-boot-starter
    1.3.2



    org.seleniumhq.selenium
    selenium-java
    2.48.1

Tips:selenium最好使用2.4.x的版本,个人测试 chrome最新版75如果使用selenium3.x的话是会报错的

  • 整合进springboot
    @Configuration
    @Slf4j
    public class WebDriverConfig {
    
        @Value("${crawler.webdriver.remote.url}")
        private String webdriverUrl;
    
        public String getWebdriverUrl() {
            return webdriverUrl;
        }
        
        @Bean
        public RemoteWebDriver webDriver(){
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.addArguments("--headless");
            chromeOptions.addArguments("--disable-gpu");
            DesiredCapabilities dc = DesiredCapabilities.chrome();
            dc.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
            try {
                RemoteWebDriver driver = new RemoteWebDriver(new URL(webdriverUrl),dc);
                return driver;
            } catch (MalformedURLException e) {
                log.error("构建webdriver失败:{}",e.getMessage());
                return null;
            }
        }
    }
    

    application.properties里面关于webdriver的配置

    crawler.webdriver.remote.url=http://127.0.0.1:9515
    
  • 爬虫的几个技巧
    1.执行某一段Js脚本
    driver.executeScript("document.getElementsByName("userid")[0].value = '"+sevenEightGuaKaoConfig.getWebsiteUserName()+"';document.getElementsByName("userpwd")[0].value = '"+sevenEightGuaKaoConfig.getWebsitePassword()+"';document.getElementsByName("log_submit")[0].click();");
    
    
    2.跳转到某个详情页并且将webdriver切换到新的tab页上
    driver.executeScript("window.open('"+url+"');");
    String[] newHandles=new String[driver.getWindowHandles().size()];
    driver.getWindowHandles().toArray(newHandles);
    WebDriver resumeDetailDriver=driver.switchTo().window(newHandles[newHandles.length-1]);
    
    3.关闭当前tab页并且将webdriver切换到跳转之前的tab页
    Actions action = new Actions(resumeDetailDriver);    action.keyDown(Keys.CONTROL).sendKeys("w").keyUp(Keys.CONTROL).sendKeys(Keys.NULL).perform();
    
    4.获取访问到的页面
    String pageSource = resumeDetailDriver.getPageSource();
    
    5.某个区域截图
    WebElement codePicWebelement = remoteWebDriver.findElement(By.id("Img"));
    File screenshot = ((TakesScreenshot)remoteWebDriver).getScreenshotAs(OutputType.FILE);
    BufferedImage fullImg = ImageIO.read(screenshot);
    Point point = codePicWebelement.getLocation();
    int eleWidth = codePicWebelement.getSize().getWidth();
    int eleHeight = codePicWebelement.getSize().getHeight();
    BufferedImage eleScreenshot= fullImg.getSubimage(point.getX(), point.getY(),eleWidth, eleHeight);
    ImageIO.write(eleScreenshot, "png", screenshot);File screenshotLocation = new File("/Users/dudycoco/program/personal_pro/666jianzhuwang/img/yzm.png");
            FileUtils.copyFile(screenshot, screenshotLocation);
    
5.后续

​ 如果想通过chrome headless来做分布式爬虫,可以通过redis来管理url的队列。在实际使用的使用的时候,chrome headless完全可以当做页面的解析器用来提取数据,访问或者并发可以通过其他的框架来实现,比如webmagic,在写爬虫的时候还是要考虑失败之后的补偿,这个也是可以用Redis来做的。
​ chrome headless的作用不仅可以用来做爬虫,还可以用来做一些自动化测试的,这里就不展开了,感兴趣的同学可以自行谷歌TestNg,cumcuber。
在做爬虫的时候,还会涉及到一些图片识别的技术,可以去看看tess之类的技术。

文章来源于互联网:Java爬虫:selenium chrome headless

发表评论